package com.corpgovernment.organization.controller;

import cn.hutool.core.util.ObjectUtil;
import com.corpgovernment.api.applytrip.enums.ApplyTripEmployeeEnum;
import com.corpgovernment.api.costcenter.model.CostCenter;
import com.corpgovernment.api.organization.bo.SyncOrgEmployeeReq;
import com.corpgovernment.api.organization.bo.SyncOrgEmployeeRsp;
import com.corpgovernment.api.organization.bo.SyncOrgInfoReq;
import com.corpgovernment.api.organization.bo.SyncOrgInfoRsp;
import com.corpgovernment.api.organization.model.org.OrgConfigInfoVo;
import com.corpgovernment.api.organization.model.org.request.GetOrgConfigRequest;
import com.corpgovernment.api.organization.model.org.response.GetOrgConfigResponse;
import com.corpgovernment.api.organization.model.user.employee.request.ListEmployeeInOrgRequest;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.enums.PayTypeEnum;
import com.corpgovernment.common.enums.*;
import com.corpgovernment.common.mq.enums.MessageBizTypeEnum;
import com.corpgovernment.common.utils.DateUtil;
import com.corpgovernment.common.utils.EncryptUtils;
import com.corpgovernment.common.utils.Null;
import com.corpgovernment.common.utils.ObjectStringTrimUtils;
import com.corpgovernment.costcenter.entity.db.MbOrgCostDefaultDepartment;
import com.corpgovernment.costcenter.entity.db.MbOrgCostInfo;
import com.corpgovernment.costcenter.mapper.MbOrgCostDefaultDepartmentMapper;
import com.corpgovernment.costcenter.mapper.MbOrgCostInfoMapper;
import com.corpgovernment.job.dao.entity.db.JobDo;
import com.corpgovernment.job.service.JobService;
import com.corpgovernment.organization.Bo.SyncEmployeeInfoBo;
import com.corpgovernment.organization.constant.OrganizationConst;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.constant.SyncImportExcelConst;
import com.corpgovernment.organization.dataloader.BasicOssClientLoader;
import com.corpgovernment.organization.dataloader.db.MbOrgInfoLoader;
import com.corpgovernment.organization.entity.SyncEmployeeCallBackRequestEntity;
import com.corpgovernment.organization.entity.SyncEmployeeRequestEntity;
import com.corpgovernment.organization.entity.SyncHumanResourcesResponseEntity;
import com.corpgovernment.organization.entity.SyncOrganizationRequestEntity;
import com.corpgovernment.organization.entity.db.*;
import com.corpgovernment.organization.enumm.CorpPayTypeEnum;
import com.corpgovernment.organization.enumm.*;
import com.corpgovernment.organization.mapper.MbOrgInfoMapper;
import com.corpgovernment.organization.mapper.MbUserOrgRelationMapper;
import com.corpgovernment.organization.metric.MetricService;
import com.corpgovernment.organization.model.org.vo.SearchMbImportExcelRecordDetailLogRequestVo;
import com.corpgovernment.organization.model.org.vo.SearchMbImportExcelRecordRequestVo;
import com.corpgovernment.organization.mq.MultiTenantSyncEmpAndOrgProducer;
import com.corpgovernment.organization.service.*;
import com.corpgovernment.organization.service.impl.CheckSyncOrgService;
import com.corpgovernment.organization.service.impl.CommonInvoiceInfoService;
import com.corpgovernment.organization.service.impl.ExpressAddressServiceImpl;
import com.corpgovernment.organization.util.ExcelUtils;
import com.corpgovernment.organization.util.IdCardUtil;
import com.corpgovernment.organization.util.StrUtils;
import com.corpgovernment.organization.util.ValidUtils;
import com.corpgovernment.organization.vo.*;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.service.RoleService;
import com.corpgovernment.redis.handler.RedisHandler;
import com.ctrip.corp.obt.generic.core.context.RequestContext;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.Conditional;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.corpgovernment.common.enums.GenderEnum.F;
import static com.corpgovernment.common.enums.GenderEnum.M;
import static com.corpgovernment.permission.config.PermissionFilter.DATA_PERMISSION_ORG_ID_LIST;


/**
 * 组织架构同步控制器
 *
 * @author lwli
 */
@RequestMapping(value = "/synchr")
@RestController
@Slf4j
public class SyncHumanResourcesController {

    @Autowired
    private IOrganizationInfoService organizationInfoService;
    @Autowired
    private IOrganizationEmployeeService organizationEmployeeService;
    @Autowired
    private MultiTenantSyncEmpAndOrgProducer multiTenantSyncEmpAndOrgProducer;
    @Autowired
    private ExcelUtils excelUtils;
    @Autowired
    private IMbImportExcelRecordService mbImportExcelRecordService;
    @Autowired
    private RedisHandler redisHandler;
    @Autowired
    private ISyncEmployeeNewService syncEmployeeNewService;
    @Autowired
    private CommonInvoiceInfoService commonInvoiceInfoService;
    @Autowired
    private ExpressAddressServiceImpl expressAddressService;
    @Autowired
    private IPostService postService;
    @Autowired
    private SyncOrgInfoService syncOrgInfoService;
    @Autowired
    private SyncOrgEmployeeService syncOrgEmployeeService;
    @Autowired
    private IOrganizationInfoService iOrganizationInfoService;
    @Autowired
    private CheckSyncOrgService checkSyncOrgService;
    @Autowired
    private MbOrgInfoLoader mbOrgInfoLoader;
    @Autowired
    private BasicOssClientLoader basicOssClientLoader;

    @Autowired
    private MbOrgInfoMapper mbOrgInfoMapper;
    @Autowired
    private IOrgConfigService orgConfigService;
    @Autowired
    private IOrgPayTypeService orgPayTypeService;
    @Autowired
    private MbOrgCostInfoMapper orgCostInfoMapper;
    @Autowired
    private MbOrgCostDefaultDepartmentMapper mbOrgCostDefaultDepartmentMapper;
    @Autowired
    private JobService jobService;
    @Autowired
    private MbUserOrgRelationMapper mbUserOrgRelationMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ISyncOrganizationService iSyncOrganizationService;




    @PostMapping("/syncOrgInfoByOpenApi")
    public SyncOrgInfoRsp syncOrgInfoByOpenApi(@RequestBody SyncOrgInfoReq request){
        log.info("syncOrgInfoByOpenApi：{}" , JsonUtils.toJsonString(request));
        ObjectStringTrimUtils.allFieldRemoveWarp(request);
        log.info("syncOrgInfoByOpenApi after：{}" , JsonUtils.toJsonString(request));

        return syncOrgInfoService.process(request);
    }



    @RequestMapping("downloadImportExcelOrg")
    public void downloadImportExcelOrg(@RequestBody SearchMbImportExcelRecordDetailLogRequestVo requestVo, HttpServletResponse response) {
        if (requestVo == null) {
            return ;
        }
        mbImportExcelRecordService.downloadImportExcelOrg(requestVo.getRecordId(),response);
    }



    /**
     * 同步组织架构（从excel中）
     *
     * @param file
     * @param notifyUrl
     * @return
     */
    @ApiOperation("excel上传组织架构")
    @PostMapping("/syncOrgInfoByExcel")
    public SyncHumanResourcesResponseEntity syncOrgInfoByExcel(@RequestParam("file") MultipartFile file, @RequestParam String defaultOrgId,@RequestParam String syncTpye, @RequestParam String defaultBusinessCode, String notifyUrl, BaseUserInfo baseUserInfo) throws Exception {
        // 从指定目录的excel中读取组织数据
        List<SyncOrganizationRequestEntity.SyncOrganizationInfoEntity> orgList = new ArrayList<>();
        if (file == null) {
            return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_ErrorExcel_Failure, false);
        }
        try {
            iSyncOrganizationService.handleEmployImport(file, baseUserInfo, syncTpye, defaultBusinessCode);
            MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, true, MetricService.ASYNC);
            return setResponse(ServiceErrorEnum.Success, true);
        }catch (Exception e){
            log.error("导入组织excel失败", e);
            MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, false, MetricService.ASYNC);
            return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_ErrorRequest_Failure, false);
        }

        //return null;

      /*  String fileUrl = basicOssClientLoader.putPrivateObject(file);

        int count;
        List<MbImportExcelRecordDetailLog> inValidList = new ArrayList<>();
        XSSFWorkbook sheets;
        Long recordId;
        try  {
            sheets = new XSSFWorkbook(file.getInputStream());
            List<OrgInfoExcelColumnVO> orgInfo = getOrgInfoExcelColumnVOS(inValidList, sheets, defaultBusinessCode);
            List<OrgContactExcelColumnVO> orgContacts = new ArrayList<>();
            List<OrgInvoiceInfoExcelColumnVO> orgInvoice = getOrgInvoiceInfoExcelColumnVOS(inValidList, sheets);
            List<OrgDeliveryInfoExcelColumnVO> orgDelivery = getOrgDeliveryInfoExcelColumnVOS(sheets);
            List<OrgPostInfoExcelColumnVO> orgPost = getOrgPostInfoExcelColumnVOS(sheets);
            count = orgInfo.size();
            List<OrgConfigExcelColumnVO> orgConfigExcelColumnVOList = getOrgConfigExcelColumnVOS(sheets);
            List<PayTypeConfigExcelColumnVO> payTypeColumnList = getPayTypeConfigExcelColumnVOS(sheets);
            Map<String, List<OrgInfoExcelColumnVO>> mapOrgInfo = Conditional.ofEmptyAble(orgInfo).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgInfoExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgInfoExcelColumnVO::getBusinessCode));
            Map<String, List<OrgContactExcelColumnVO>> mapOrgContacts = Conditional.ofEmptyAble(orgContacts).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgContactExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgContactExcelColumnVO::getBusinessCode));
            Map<String, List<OrgInvoiceInfoExcelColumnVO>> mapOrgInvoice = Conditional.ofEmptyAble(orgInvoice).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgInvoiceInfoExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgInvoiceInfoExcelColumnVO::getBusinessCode));
            Map<String, List<OrgDeliveryInfoExcelColumnVO>> mapOrgDelivery = Optional.ofNullable(orgDelivery).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgDeliveryInfoExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgDeliveryInfoExcelColumnVO::getBusinessCode));
            Map<String, List<OrgPostInfoExcelColumnVO>> mapOrgPost = Optional.ofNullable(orgPost).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgPostInfoExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgPostInfoExcelColumnVO::getBusinessCode));
            Map<String, List<OrgConfigExcelColumnVO>> mapOrgConfig = Optional.ofNullable(orgConfigExcelColumnVOList).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgConfigExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(OrgConfigExcelColumnVO::getBusinessCode));
            Map<String, List<PayTypeConfigExcelColumnVO>> mapPayType = Optional.ofNullable(payTypeColumnList).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new PayTypeConfigExcelColumnVO()) && StringUtils.isNotBlank(e.getBusinessCode()))
                    .collect(Collectors.groupingBy(PayTypeConfigExcelColumnVO::getBusinessCode));
            // 排序并获取有用的组织
            orgInfo = filterRepeatOrgId(mapOrgInfo, inValidList);
            //orgInfo = filterRepeatOrgIdBusinessCode(orgInfo, inValidList);
            orgInfo = this.sortOrgList(orgInfo, baseUserInfo, inValidList);
            log.info("排序完之后的数据：{}", JsonUtils.toJsonString(orgInfo));
            List<OrgInfoExcelColumnVO> orgInfoExcelColumnVOS = orgInfo.stream().filter(Objects::nonNull).collect(Collectors.toList());
            //转换参数
            for (OrgInfoExcelColumnVO org : orgInfoExcelColumnVOS) {
                SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp = new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity();
                temp.setIsDelete(CommonEnum.Y.getDesc().equals(org.getIsDelete()) || CommonEnum.Y.getCode().equals(org.getIsDelete()));
                temp.setLineNo(org.getLineNo());
                SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.BasicInfoEntity basic = new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.BasicInfoEntity();
                basic.setOrgId(org.getOrgId());
                basic.setName(org.getName());
                basic.setType(OrgTypeEnum.D.getDesc().equals(org.getType()) ? OrgTypeEnum.D.getCode() : OrgTypeEnum.C.getCode());
                basic.setParentOrgId(org.getParentOrgId());
                basic.setIsActive(!CommonEnum.N.getDesc().equals(org.getIsActive()));
                //basic.setTopOrgId(org.getTopOrgId());
                basic.setBusinessCode(org.getBusinessCode());
                basic.setParentBusinessCode(org.getParentBusinessCode());
                basic.setCostCenterInfo(org.getCostCenterInfo());
                basic.setCostCenterInfoDefault(org.getCostCenterInfoDefault());
                basic.setLineNo(temp.getLineNo());
                basic.setMainLineNo(temp.getLineNo());
                log.info("基础信息：" + JsonUtils.toJsonString(basic));
                temp.setBasicInfo(basic);
                // 塞入联系人信息
                extractContacts(mapOrgContacts, org, temp);
                // 塞入发票信息
                extractInvoice(mapOrgInvoice, org, temp);
                // 塞入配送信息
                extractDelivery(mapOrgDelivery, org, temp);
                // 塞入组织配置
                extractOrgConfig(mapOrgConfig, org, temp);
                // 塞入配置信息
                extractPayType(mapPayType, org, temp);
                // 塞入邮寄信息
                extractPostInfo(mapOrgPost, org, temp);
                ServiceErrorEnum checkResult = checkSyncOrgService.checkOrganizationRequest(temp,inValidList);
                if (ServiceErrorEnum.Success.getErrorCode().equals(checkResult.getErrorCode()) && !inValidList.stream().filter(s -> s.getLineNo().equals(temp.getLineNo())).findFirst().isPresent()) {
                    orgList.add(temp);
                }
            }
            handleDeliveryAddress(orgList, mapOrgInfo, mapOrgDelivery);
            log.info("组织完全数据：{}", JsonUtils.toJsonString(orgList));
            // 按照行号排序
            orgList = orgList.stream().sorted(Comparator.comparing(t->Integer.valueOf(t.getLineNo()))).collect(Collectors.toList());
            recordId = saveImportRecord(file,fileUrl,baseUserInfo, count, inValidList);
            redisHandler.setValue(SyncImportExcelConst.IMPORT_TOTAL + recordId, orgList.size(), 60 * 20);
        } catch (Exception ex) {
            log.error("导入组织组装excel失败", ex);
            return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_ErrorRequest_Failure, false);
        }
        log.info("组织信息2:{}", JsonUtils.toJsonString(orgList));
        return sendOrgMsg(syncTpye,orgList, notifyUrl, recordId, baseUserInfo, inValidList, recordId);*/
    }

    /**
     * 如果是部门且没有配送地址，使用父级的
     */
    private void handleDeliveryAddress(List<SyncOrganizationRequestEntity.SyncOrganizationInfoEntity> orgList,
                                       Map<String, List<OrgInfoExcelColumnVO>> mapOrgInfo,
                                       Map<String, List<OrgDeliveryInfoExcelColumnVO>> mapOrgDelivery) {
        if (CollectionUtils.isEmpty(orgList)) {
            return;
        }
        orgList.forEach(item -> {
            SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.BasicInfoEntity basicInfo = item.getBasicInfo();
            // 如果是部门没有配置配送地址 将公司配置的配送地址填补进来
            List<OrgDeliveryInfoExcelColumnVO> orgDeliveryInfoExcelColumnVOS =
                    mapOrgDelivery.get(basicInfo.getBusinessCode());
            if (OrgTypeEnum.D.getCode().equals(basicInfo.getType())
                    && (CollectionUtils.isEmpty(orgDeliveryInfoExcelColumnVOS)
                    || orgDeliveryInfoExcelColumnVOS.size() == 0)) {
                List<OrgDeliveryInfoExcelColumnVO> orgDeliveryInfoNew =
                        this.deliveryRecursion(mapOrgInfo, mapOrgDelivery, basicInfo.getParentOrgId());

                item.setDeliveryAddressList(orgDeliveryInfoNew.stream().filter(Objects::nonNull).map(od -> {
                    SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.DeliveryAddressEntity tempDelivery =
                            new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.DeliveryAddressEntity();
                    tempDelivery.setProvinceName(od.getProvinceName());
                    tempDelivery.setCityName(od.getCityName());
                    tempDelivery.setDistrictName(od.getDistrictName());
                    tempDelivery.setAddress(od.getAddress());
                    tempDelivery.setPostCode(od.getPostCode());
                    tempDelivery.setRecipientName(od.getRecipientName());
                    if (StringUtils.isEmpty(od.getRecipientCountryCode())) {
                        od.setRecipientCountryCode(PhoneCountryCodeEnum.CN.getCountryCode());
                    }
                    tempDelivery.setRecipientCountryCode(od.getRecipientCountryCode().startsWith("+")
                            ? od.getRecipientCountryCode() : "+" + od.getRecipientCountryCode());
                    tempDelivery.setRecipientPhone(od.getRecipientPhone());
                    tempDelivery.setIsDefault(CommonEnum.Y.name().equals(od.getIsDefault()));
                    return tempDelivery;
                }).collect(Collectors.toList()));
            }

        });

    }

    private void extractPostInfo(Map<String, List<OrgPostInfoExcelColumnVO>> mapOrgPost, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        List<OrgPostInfoExcelColumnVO> listOrgPost =
                mapOrgPost.getOrDefault(org.getBusinessCode(), new ArrayList<>());
        temp.setPostInfoList(listOrgPost.stream().filter(Objects::nonNull).map(e -> {
            SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.PostInfoEntity postInfoEntity =
                    new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.PostInfoEntity();
            postInfoEntity.setName(e.getPostName());
            postInfoEntity.setLineNo(e.getLineNo());
            postInfoEntity.setMainLineNo(org.getLineNo());
            return postInfoEntity;
        }).collect(Collectors.toList()));
    }

    private void extractPayType(Map<String, List<PayTypeConfigExcelColumnVO>> mapPayType, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        if (MapUtils.isNotEmpty(mapPayType)) {
            List<PayTypeConfigExcelColumnVO> listPayType = mapPayType.get(org.getBusinessCode());
            if (CollectionUtils.isNotEmpty(listPayType)) {
                temp.setPayTypeConfigList(listPayType.stream().filter(Objects::nonNull).map(od -> {
                    SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.PayTypeConfigEntity tempDelivery = new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.PayTypeConfigEntity();
                    tempDelivery.setCarPub(od.getCar());
                    tempDelivery.setBusinessCode(od.getBusinessCode());
                    tempDelivery.setHotelPub(od.getHotel());
                    tempDelivery.setFlightPub(od.getFlight());
                    tempDelivery.setFlightintlPub(od.getFlightintl());
                    tempDelivery.setHotelintlPub(od.getHotelintl());
                    tempDelivery.setTrainPub(od.getTrain());
                    tempDelivery.setMainLineNo(org.getLineNo());
                    tempDelivery.setLineNo(od.getLineNo());
                    return tempDelivery;
                }).collect(Collectors.toList()));
            }
        }
    }

    private void extractOrgConfig(Map<String, List<OrgConfigExcelColumnVO>> mapOrgConfig, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        if (MapUtils.isNotEmpty(mapOrgConfig)) {
            List<OrgConfigExcelColumnVO> listOrgConfig = mapOrgConfig.get(org.getBusinessCode());
            if (CollectionUtils.isNotEmpty(listOrgConfig)) {
                temp.setOrgConfigEntityList(listOrgConfig.stream().filter(Objects::nonNull).map(od -> {
                    SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.OrgConfigEntity orgConfigEntity = new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.OrgConfigEntity();
                    orgConfigEntity.setBusinessCode(od.getBusinessCode());
                    orgConfigEntity.setProjectIsNeed(od.getProjectIsNeed());
                    orgConfigEntity.setCostCenterIsNeed(od.getCostCenterIsNeed());
                    orgConfigEntity.setLineNo(od.getLineNo());
                    orgConfigEntity.setMainLineNo(org.getLineNo());
                    return orgConfigEntity;
                }).collect(Collectors.toList()));
            }
        }
    }

    private  void extractDelivery(Map<String, List<OrgDeliveryInfoExcelColumnVO>> mapOrgDelivery, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        if (MapUtils.isNotEmpty(mapOrgDelivery)) {
            List<OrgDeliveryInfoExcelColumnVO> listOrgDelivery = mapOrgDelivery.get(org.getBusinessCode());
            if (CollectionUtils.isNotEmpty(listOrgDelivery)) {
                temp.setDeliveryAddressList(listOrgDelivery.stream().filter(Objects::nonNull).map(od -> {
                    SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.DeliveryAddressEntity tempDelivery = new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.DeliveryAddressEntity();
                    tempDelivery.setProvinceName(od.getProvinceName());
                    tempDelivery.setCityName(od.getCityName());
                    tempDelivery.setDistrictName(od.getDistrictName());
                    tempDelivery.setAddress(od.getAddress());
                    tempDelivery.setPostCode(od.getPostCode());
                    tempDelivery.setRecipientName(od.getRecipientName());
                    // PhoneCountryCodeEnum deliveryCountryCodeEnum = Optional.ofNullable(PhoneCountryCodeEnum.getByDesc(od.getRecipientCountryCode())).orElse(PhoneCountryCodeEnum.CN);
                    if (StringUtils.isEmpty(od.getRecipientCountryCode())) {
                        od.setRecipientCountryCode(PhoneCountryCodeEnum.CN.getCountryCode());
                    }
                    tempDelivery.setRecipientCountryCode(od.getRecipientCountryCode().startsWith("+") ? od.getRecipientCountryCode() : "+" + od.getRecipientCountryCode());
                    tempDelivery.setRecipientPhone(od.getRecipientPhone());
                    tempDelivery.setIsDefault(CommonEnum.Y.name().equals(od.getIsDefault()));
                    tempDelivery.setMainLineNo(org.getLineNo());
                    tempDelivery.setLineNo(od.getLineNo());
                    return tempDelivery;
                }).collect(Collectors.toList()));
            }
        }
    }

    private  void extractInvoice(Map<String, List<OrgInvoiceInfoExcelColumnVO>> mapOrgInvoice, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        if (MapUtils.isNotEmpty(mapOrgInvoice)) {
            List<OrgInvoiceInfoExcelColumnVO> listOrgInvoice = mapOrgInvoice.get(org.getBusinessCode());
            if (CollectionUtils.isNotEmpty(listOrgInvoice)) {
                temp.setInvoiceList(listOrgInvoice.stream().filter(Objects::nonNull).map(oi -> {
                    SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.InvoiceInfoEntity tempInvoice =
                            new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.InvoiceInfoEntity();
                    tempInvoice.setInvoiceTitle(oi.getInvoiceTitle());
                    tempInvoice.setTaxId(oi.getTaxId());
                    tempInvoice.setAccountBank(oi.getAccountBank());
                    tempInvoice.setAccountCardNo(oi.getAccountCardNo());
                    tempInvoice.setCorporationPhone(oi.getCorporationPhone());
                    tempInvoice.setCorporationAddress(oi.getCorporationAddress());
                    tempInvoice.setMainLineNo(org.getLineNo());
                    tempInvoice.setLineNo(oi.getLineNo());
                    return tempInvoice;
                }).collect(Collectors.toList()));
            }
        }
    }

    private  void extractContacts(Map<String, List<OrgContactExcelColumnVO>> mapOrgContacts, OrgInfoExcelColumnVO org, SyncOrganizationRequestEntity.SyncOrganizationInfoEntity temp) {
        if (MapUtils.isNotEmpty(mapOrgContacts)) {
            List<OrgContactExcelColumnVO> listOrgContacts = mapOrgContacts.get(org.getBusinessCode());
            if (CollectionUtils.isNotEmpty(listOrgContacts)) {
                OrgContactExcelColumnVO oc = listOrgContacts.get(0);
                SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.ContactInfoEntity tempContact =
                        new SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.ContactInfoEntity();
                tempContact.setContactName(oc.getContactName());
                tempContact.setContactEmail(oc.getContactEmail());
                if (StringUtils.isEmpty(oc.getContactCountryCode())) {
                    oc.setContactCountryCode(PhoneCountryCodeEnum.CN.getCountryCode());
                }
                tempContact.setContactCountryCode(oc.getContactCountryCode().startsWith("+") ? oc.getContactCountryCode() : "+" + oc.getContactCountryCode());
                tempContact.setContactPhone(oc.getContactPhone());
                tempContact.setLineNo(oc.getLineNo());
                tempContact.setMainLineNo(temp.getLineNo());
                temp.setContactInfo(tempContact);
            }
        }
    }

    /**
     * 保存
     */
    private Long saveImportRecord(MultipartFile file, String fileUrl ,BaseUserInfo baseUserInfo, int count, List<MbImportExcelRecordDetailLog> inValidList) {
        MbImportExcelRecord mbImportExcelRecord = new MbImportExcelRecord();
        mbImportExcelRecord.setUid(baseUserInfo.getUid());
        mbImportExcelRecord.setOrgId(baseUserInfo.getOrgId());
        mbImportExcelRecord.setCorpId(baseUserInfo.getCorpId());
        mbImportExcelRecord.setFileName(file.getOriginalFilename());
        mbImportExcelRecord.setFileUrl(fileUrl);
        mbImportExcelRecord.setStatus(MbImportExcelRecordStatusEnum.E.getDealCode());
        mbImportExcelRecord.setType(MbImportExcelRecordTypeEnum.ORG.getCode());
        mbImportExcelRecord.setDatachangeCreatetime(new Date());
        mbImportExcelRecord.setTotalCount(count);
        if (CollectionUtils.isEmpty(inValidList)){
            mbImportExcelRecord.setFailCount(0);
        } else {
            int failedNum = (int) inValidList.stream().map(MbImportExcelRecordDetailLog::getMainLineNo).distinct().count();
            mbImportExcelRecord.setFailCount(failedNum);
        }

        mbImportExcelRecordService.insertRecord(mbImportExcelRecord);
        return mbImportExcelRecord.getId();
    }

    private List<PayTypeConfigExcelColumnVO> getPayTypeConfigExcelColumnVOS(XSSFWorkbook sheets) {
        XSSFSheet sheetPayConfig = sheets.getSheet("支付设置");
        List<PayTypeConfigExcelColumnVO> payTypeColumnList =
                excelUtils.getBeanListFromExcel(sheetPayConfig, PayTypeConfigExcelColumnVO.class);
        log.info("支付设置：{}", JsonUtils.toJsonString(payTypeColumnList));
        return payTypeColumnList;
    }

    private List<OrgConfigExcelColumnVO> getOrgConfigExcelColumnVOS(XSSFWorkbook sheets) {
        XSSFSheet sheetOrgConfig = sheets.getSheet("组织设置");
        List<OrgConfigExcelColumnVO> orgConfigExcelColumnVOList = excelUtils.getBeanListFromExcel(sheetOrgConfig, OrgConfigExcelColumnVO.class);
        log.info("组织设置：{}", JsonUtils.toJsonString(orgConfigExcelColumnVOList));
        return orgConfigExcelColumnVOList;
    }

    private List<OrgPostInfoExcelColumnVO> getOrgPostInfoExcelColumnVOS(XSSFWorkbook sheets) {
        XSSFSheet sheetPost = sheets.getSheet("职级");
        List<OrgPostInfoExcelColumnVO> orgPost = excelUtils.getBeanListFromExcel(sheetPost, OrgPostInfoExcelColumnVO.class);
        log.info("职级信息：{}", JsonUtils.toJsonString(orgPost));
        return orgPost;
    }

    private List<OrgDeliveryInfoExcelColumnVO> getOrgDeliveryInfoExcelColumnVOS(XSSFWorkbook sheets) {
        XSSFSheet sheetDelivery = sheets.getSheet("配送");
        List<OrgDeliveryInfoExcelColumnVO> orgDelivery = excelUtils.getBeanListFromExcel(sheetDelivery, OrgDeliveryInfoExcelColumnVO.class);
        log.info("配送信息：{}", JsonUtils.toJsonString(orgDelivery));
        return orgDelivery;
    }

    private List<OrgInvoiceInfoExcelColumnVO> getOrgInvoiceInfoExcelColumnVOS(List<MbImportExcelRecordDetailLog> inValidList, XSSFWorkbook sheets) {
        XSSFSheet sheetInvoice = sheets.getSheet("发票");
        List<OrgInvoiceInfoExcelColumnVO> orgInvoice = excelUtils.getBeanListFromExcel(sheetInvoice, OrgInvoiceInfoExcelColumnVO.class);
        log.info("发票信息：{}", JsonUtils.toJsonString(orgInvoice));
        checkInvoiceInfoList(orgInvoice, inValidList,OrgInfoSheetEnum.INVOICE);
        return orgInvoice;
    }

    private List<OrgInfoExcelColumnVO> getOrgInfoExcelColumnVOS(List<MbImportExcelRecordDetailLog> inValidList, XSSFWorkbook sheets, String defaultBusinessCode) throws IllegalAccessException {
        XSSFSheet sheetOrg = sheets.getSheet("组织");
        List<OrgInfoExcelColumnVO> orgInfo = excelUtils.getBeanListFromExcel(sheetOrg, OrgInfoExcelColumnVO.class);
        log.info("组织信息1：{}", JsonUtils.toJsonString(orgInfo));
        orgInfo = filterAllNull(orgInfo);
        checkOrgInfoList(orgInfo, inValidList,OrgInfoSheetEnum.INFO);
        // 数据处理
        orgInfo = Conditional.ofEmptyAble(orgInfo).orElse(new ArrayList<>()).stream().filter(x -> StringUtils.isNotBlank(x.getBusinessCode())).peek(x -> {
            if (StringUtils.isEmpty(x.getParentBusinessCode()) && !defaultBusinessCode.equalsIgnoreCase(x.getBusinessCode())) {
                x.setParentBusinessCode(defaultBusinessCode);
            }
            //x.setOrgId(UUID.randomUUID().toString());
            if (StringUtils.isEmpty(x.getBusinessCode())) {
                x.setBusinessCode(x.getOrgId());
            }
        }).collect(Collectors.toList());
        return orgInfo;
    }


    private List<OrgInfoExcelColumnVO> filterRepeatOrgId(Map<String, List<OrgInfoExcelColumnVO>> mapOrgInfo, List<MbImportExcelRecordDetailLog> inValidList) {
        List<OrgInfoExcelColumnVO> filterRepeatAfterData = new ArrayList<>();
        List<OrgInfoExcelColumnVO> repeatData = new ArrayList<>();
        if (MapUtils.isNotEmpty(mapOrgInfo)) {
            for (List<OrgInfoExcelColumnVO> entry : mapOrgInfo.values()) {
                if (entry.size() == 1) {
                    filterRepeatAfterData.addAll(entry);
                } else {
                    repeatData.addAll(entry);
                }
            }
        }
        log.info("组织信息导入时重复数据：{}", JsonUtils.toJsonString(repeatData));
        log.info("组织信息导入时没有重复数据: {}", JsonUtils.toJsonString(filterRepeatAfterData));
        for (OrgInfoExcelColumnVO data : repeatData) {
            MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
            mbImportExcelRecordDetailLog.setSheetIndex(OrgInfoSheetEnum.INFO.getIndex());
            mbImportExcelRecordDetailLog.setSheetName(OrgInfoSheetEnum.INFO.getName());
            mbImportExcelRecordDetailLog.setLineNo(data.getLineNo());
            mbImportExcelRecordDetailLog.setMainLineNo(data.getLineNo());
            mbImportExcelRecordDetailLog.setStatus("F");
            mbImportExcelRecordDetailLog.setMessage(ImportExcelRecordDetailLogErrorMessageEnum.L.getErrorMessage());
            mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
            mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
            inValidList.add(mbImportExcelRecordDetailLog);
        }
        return filterRepeatAfterData;
    }

    private void checkInvoiceInfoList(List<OrgInvoiceInfoExcelColumnVO> orgInvoice, List<MbImportExcelRecordDetailLog> inValidList,OrgInfoSheetEnum orgInfoSheetEnum) {
        if (CollectionUtils.isNotEmpty(orgInvoice)) {
            for (OrgInvoiceInfoExcelColumnVO vo : orgInvoice) {
                if ((StringUtils.isNotBlank(vo.getAccountBank()) ||
                        StringUtils.isNotBlank(vo.getInvoiceTitle()) ||
                        StringUtils.isNotBlank(vo.getTaxId()) ||
                        StringUtils.isNotBlank(vo.getAccountCardNo()) ||
                        StringUtils.isNotBlank(vo.getCorporationPhone()) ||
                        StringUtils.isNotBlank(vo.getCorporationAddress())) && StringUtils.isBlank(vo.getBusinessCode())) {
                    addInValidList(inValidList, orgInfoSheetEnum.getIndex(),orgInfoSheetEnum.getName(),vo.getLineNo(), vo.getLineNo(), ImportExcelRecordDetailLogErrorMessageEnum.M.getErrorMessage());
                }
            }
        }
    }

    private void checkOrgInfoList(List<OrgInfoExcelColumnVO> orgInfo, List<MbImportExcelRecordDetailLog> inValidList,OrgInfoSheetEnum sheetEnum) {
        if (CollectionUtils.isEmpty(orgInfo)) {
            addInValidList(inValidList, sheetEnum.getIndex(),sheetEnum.getName(),"1","1",
                    ImportExcelRecordDetailLogErrorMessageEnum.N.getErrorMessage());
            return;
        }
        for (OrgInfoExcelColumnVO vo : orgInfo) {
            if (StringUtils.isEmpty(vo.getBusinessCode())) {
                addInValidList(inValidList, sheetEnum.getIndex(),sheetEnum.getName(),vo.getLineNo(),vo.getLineNo(),
                    ImportExcelRecordDetailLogErrorMessageEnum.O.getErrorMessage());
            }
            if (vo.getBusinessCode().length() > 50) {
                addInValidList(inValidList, sheetEnum.getIndex(),sheetEnum.getName(),vo.getLineNo(),vo.getLineNo(),
                    ImportExcelRecordDetailLogErrorMessageEnum.J.getErrorMessage());
            }
            if (StringUtils.isBlank(vo.getType()) || Objects.isNull(OrgTypeEnum.getByDesc(vo.getType()))) {
                addInValidList(inValidList,sheetEnum.getIndex(),sheetEnum.getName(), vo.getLineNo(),vo.getLineNo(),
                    ImportExcelRecordDetailLogErrorMessageEnum.P.getErrorMessage());
            }
        }
    }

    private List<OrgInfoExcelColumnVO> filterAllNull(List<OrgInfoExcelColumnVO> orgInfo) throws IllegalAccessException {
        List<OrgInfoExcelColumnVO> newOrgInfos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(orgInfo)) {
            for (OrgInfoExcelColumnVO vo : orgInfo) {
                boolean exists = false;
                Field[] declaredField = vo.getClass().getDeclaredFields();
                for (Field field:declaredField){
                    field.setAccessible(true);
                    Object obj = field.get(vo);
                    if (Objects.nonNull(obj) && !"lineNo".equals(field.getName())){
                        exists = true;
                    }
                }
                if (!exists){
                    continue;
                }
                newOrgInfos.add(vo);
            }
        }
        return newOrgInfos;
    }

    private List<OrgInfoExcelColumnVO> filterRepeatOrgIdBusinessCode(List<OrgInfoExcelColumnVO> orgInfo, List<MbImportExcelRecordDetailLog> inValidList) {
        List<OrgInfoExcelColumnVO> filterRepeatAfterData = new ArrayList<>();
        List<OrgInfoExcelColumnVO> repeatData = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orgInfo)) {
            Map<String, List<OrgInfoExcelColumnVO>> mapOrgInfo = Optional.ofNullable(orgInfo).orElse(new ArrayList<>()).stream()
                    .filter(e -> Objects.nonNull(e) && !Objects.equals(e, new OrgInfoExcelColumnVO())).collect(Collectors.groupingBy(OrgInfoExcelColumnVO::getBusinessCode));
            if (MapUtils.isNotEmpty(mapOrgInfo)) {
                for (List<OrgInfoExcelColumnVO> entry : mapOrgInfo.values()) {
                    if (entry.size() == 1) {
                        filterRepeatAfterData.addAll(entry);
                    }
                }
            }
            List<MbOrgInfo> mbOrgInfos = Optional.ofNullable(organizationInfoService.listByBusinessCode(filterRepeatAfterData.stream().map(OrgInfoExcelColumnVO::getBusinessCode).collect(Collectors.toList()))).orElse(new ArrayList<>());
            Map<String, MbOrgInfo> collect = mbOrgInfos.stream()
                    .collect(Collectors.toMap(MbOrgInfo::getBusinessCode, Function.identity(), (o1, o2) -> o1));
            Iterator<OrgInfoExcelColumnVO> iterator = filterRepeatAfterData.iterator();
            while (iterator.hasNext()) {
                OrgInfoExcelColumnVO next = iterator.next();
                if(CommonEnum.Y.getDesc().equals(next.getIsDelete())){
                    repeatData.add(next);
                    continue;
                }
                if (collect.containsKey(next.getBusinessCode())) {
                    MbOrgInfo mbOrgInfo = collect.get(next.getBusinessCode());
                    if (!mbOrgInfo.getOrgId().equalsIgnoreCase(next.getOrgId())) {
                        MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
                        mbImportExcelRecordDetailLog.setSheetIndex(OrgInfoSheetEnum.INFO.getIndex());
                        mbImportExcelRecordDetailLog.setSheetName(OrgInfoSheetEnum.INFO.getName());
                        mbImportExcelRecordDetailLog.setLineNo(next.getLineNo());
                        mbImportExcelRecordDetailLog.setMainLineNo(next.getLineNo());
                        mbImportExcelRecordDetailLog.setStatus("F");
                        mbImportExcelRecordDetailLog.setMessage(ImportExcelRecordDetailLogErrorMessageEnum.I.getErrorMessage());
                        mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
                        mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
                        inValidList.add(mbImportExcelRecordDetailLog);
                        continue;
                    }
                }
                repeatData.add(next);
            }
        }
        return repeatData;
    }

    public List<OrgDeliveryInfoExcelColumnVO> deliveryRecursion(Map<String, List<OrgInfoExcelColumnVO>> mapOrgInfo, Map<String, List<OrgDeliveryInfoExcelColumnVO>> mapOrgDelivery, String orgId) {
        List<OrgInfoExcelColumnVO> orgInfoExcelColumnVOS = mapOrgInfo.get(orgId);
        if (CollectionUtils.isNotEmpty(orgInfoExcelColumnVOS) && orgInfoExcelColumnVOS.size() > 0) {
            OrgInfoExcelColumnVO orgInfoExcelColumnVO = orgInfoExcelColumnVOS.get(0);
            //公司
            if (OrgTypeEnum.C.getDesc().equals(orgInfoExcelColumnVO.getType())) {
                return CollectionUtils.isEmpty(mapOrgDelivery.get(orgInfoExcelColumnVO.getOrgId())) ? new ArrayList<>() : mapOrgDelivery.get(orgInfoExcelColumnVO.getOrgId());
            } else {
                return deliveryRecursion(mapOrgInfo, mapOrgDelivery, orgInfoExcelColumnVO.getParentOrgId());
            }
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 组织排序
     *
     * @param orgList
     * @return
     */
    private List<OrgInfoExcelColumnVO> sortOrgList(List<OrgInfoExcelColumnVO> orgList, BaseUserInfo baseUserInfo, List<MbImportExcelRecordDetailLog> inValidList) {
        List<MbOrgInfo> mbOrgInfos = Optional.ofNullable(organizationInfoService.listByBusinessCode(orgList.stream().map(OrgInfoExcelColumnVO::getParentBusinessCode).collect(Collectors.toList()))).orElse(new ArrayList<>());
        Set<String> businessIdsInSystem = mbOrgInfos.stream().filter(o -> o != null && StringUtils.isNotBlank(o.getBusinessCode()))
                .map(MbOrgInfo::getBusinessCode).collect(Collectors.toSet());
        List<OrgInfoExcelColumnVO> sortedList = new ArrayList<>();
        Set<String> sortListOrg = new HashSet<>();
        List<String> parentIds = new ArrayList<>();
        parentIds.add(null);
        parentIds.addAll(businessIdsInSystem);
        while (CollectionUtils.isNotEmpty(parentIds)) {
            List<OrgInfoExcelColumnVO> tempList = new ArrayList<>();
            for (OrgInfoExcelColumnVO org : orgList) {
                if (parentIds.contains(org.getParentBusinessCode())) {
                    tempList.add(org);
                }
            }
            sortedList.addAll(tempList.stream().filter(x -> !sortListOrg.contains(x.getBusinessCode())).collect(Collectors.toList()));
            sortListOrg.addAll(tempList.stream().map(OrgInfoExcelColumnVO::getBusinessCode).collect(Collectors.toList()));
            parentIds = tempList.stream().map(OrgInfoExcelColumnVO::getBusinessCode).distinct().collect(Collectors.toList());
        }
        orgList.removeAll(sortedList);
        MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = null;
        for (OrgInfoExcelColumnVO temp : orgList) {
            mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
            mbImportExcelRecordDetailLog.setSheetIndex(OrgInfoSheetEnum.INFO.getIndex());
            mbImportExcelRecordDetailLog.setSheetName(OrgInfoSheetEnum.INFO.getName());
            mbImportExcelRecordDetailLog.setLineNo(temp.getLineNo());
            mbImportExcelRecordDetailLog.setMainLineNo(temp.getLineNo());
            mbImportExcelRecordDetailLog.setStatus("F");
            mbImportExcelRecordDetailLog.setMessage(ImportExcelRecordDetailLogErrorMessageEnum.A.getErrorMessage());
            mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
            mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
            inValidList.add(mbImportExcelRecordDetailLog);
        }
        List<OrgInfoExcelColumnVO> tempRemoveList = sortedList.stream().filter(x -> "Y".equals(x.getIsDelete())).collect(Collectors.toList());
        //保证先删除(子->父)，再添加(父->子)
        sortedList.removeAll(tempRemoveList);
        Collections.reverse(tempRemoveList);
        sortedList.addAll(0, tempRemoveList);
        return sortedList;
    }

    private void addInValidList(List<MbImportExcelRecordDetailLog> inValidList, Integer sheetIndex, String sheetName, String lineNo, String mainLineNo, String message) {
        MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
        mbImportExcelRecordDetailLog.setSheetIndex(sheetIndex);
        mbImportExcelRecordDetailLog.setSheetName(sheetName);
        mbImportExcelRecordDetailLog.setMainLineNo(mainLineNo);
        mbImportExcelRecordDetailLog.setLineNo(lineNo);
        mbImportExcelRecordDetailLog.setStatus("F");
        mbImportExcelRecordDetailLog.setMessage(message);
        mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
        mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
        inValidList.add(mbImportExcelRecordDetailLog);
    }




    /**
     * 发送组织架构mq
     *
     * @param orgList
     * @param notifyUrl
     * @param inValidList
     * @param recordId
     * @return
     */
    private SyncHumanResourcesResponseEntity sendOrgMsg( String syncTpye,List<SyncOrganizationRequestEntity.SyncOrganizationInfoEntity> orgList, String notifyUrl, Long record, BaseUserInfo baseUserInfo, List<MbImportExcelRecordDetailLog> inValidList, Long recordId) throws Exception {
        try {
            // 去除list中的null
            orgList = Optional.ofNullable(orgList).orElse(new ArrayList<>()).stream().filter(Objects::nonNull).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(orgList)) {
                MbImportExcelRecord recordResult = mbImportExcelRecordService.getRecordById(record);
                MbImportExcelRecord updateRecord = new MbImportExcelRecord();
                updateRecord.setId(record);
                updateRecord.setFailCount(recordResult.getTotalCount());
                updateRecord.setStatus(MbImportExcelRecordStatusEnum.F.getDealCode());
                mbImportExcelRecordService.updateRecord(updateRecord);
                inValidList.forEach(inValidItem -> inValidItem.setRecordId(recordId));
                mbImportExcelRecordService.batchInsertRecordDetailLog(inValidList);
                log.info("插入记录：{}", JsonUtils.toJsonString(inValidList));
                MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, false, MetricService.ASYNC);
                return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_ErrorRequest_Failure, false);
            }
            orgList.forEach(org -> {
                if (CollectionUtils.isNotEmpty(org.getDeliveryAddressList())) {
                    org.getDeliveryAddressList().removeIf(Objects::isNull);
                }
                if (CollectionUtils.isNotEmpty(org.getInvoiceList())) {
                    org.getInvoiceList().removeIf(Objects::isNull);
                }
            });

            // 验证存在于系统中的组织
            List<String> businessCodeList = orgList.stream()
                    .filter(o -> BooleanUtils.isNotTrue(o.getIsDelete()) && o.getBasicInfo() != null && StringUtils.isNotBlank(o.getBasicInfo().getBusinessCode()))
                    .map(o -> o.getBasicInfo().getBusinessCode()).distinct().collect(Collectors.toList());
            List<MbOrgInfo> mbOrgInfos = Optional.ofNullable(organizationInfoService.listByBusinessCode(businessCodeList)).orElse(new ArrayList<>());
            Set<String> businessCodeInSystem = mbOrgInfos.stream().filter(o -> o != null && StringUtils.isNotBlank(o.getBusinessCode()))
                    .map(MbOrgInfo::getBusinessCode).collect(Collectors.toSet());

            // 推送消息
            Boolean errorFlag = false;
            for (SyncOrganizationRequestEntity.SyncOrganizationInfoEntity o : orgList) {
                try {
                    o.setRecordId(record);
                    // 新增
                    if(SyncEmployeeInfoBo.SyncType.ADD.getDesc().equals(syncTpye)){
                        if (BooleanUtils.isTrue(o.getIsDelete())) {
                            multiTenantSyncEmpAndOrgProducer.sendSyncOrgMsg(o, notifyUrl, MessageBizTypeEnum.SYNC_ORGANIZATION_DELETE, baseUserInfo, inValidList, recordId);
                            continue;
                        }
                        if (businessCodeInSystem.contains(o.getBasicInfo().getBusinessCode())){
                            ServiceErrorEnum serviceErrorEnum = ServiceErrorEnum.SyncHumanResources_NewError;
                            serviceErrorEnum.setErrorMessage(ImportExcelRecordDetailLogErrorMessageEnum.SyncHumanResources_SyncOrgInfo_Business_Code_Is_Exist.getErrorMessage());
                            MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
                            mbImportExcelRecordDetailLog.setLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setMainLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setStatus("F");
                            mbImportExcelRecordDetailLog.setMessage(ImportExcelRecordDetailLogErrorMessageEnum.A.getErrorMessage());
                            mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
                            mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
                            inValidList.add(mbImportExcelRecordDetailLog);
                            continue;
                        }
                        multiTenantSyncEmpAndOrgProducer.sendSyncOrgMsg(o, notifyUrl, MessageBizTypeEnum.SYNC_ORGANIZATION_ADD, baseUserInfo, inValidList, recordId);
                    }
                    // 修改
                    if(SyncEmployeeInfoBo.SyncType.UPDATE.getDesc().equals(syncTpye)){
                        if (BooleanUtils.isTrue(o.getIsDelete())) {
                            multiTenantSyncEmpAndOrgProducer.sendSyncOrgMsg(o, notifyUrl, MessageBizTypeEnum.SYNC_ORGANIZATION_DELETE, baseUserInfo, inValidList, recordId);
                            continue;
                        }
                        if (!businessCodeInSystem.contains(o.getBasicInfo().getBusinessCode())){
                            MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
                            mbImportExcelRecordDetailLog.setLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setMainLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setStatus("F");
                            mbImportExcelRecordDetailLog.setMessage(ImportExcelRecordDetailLogErrorMessageEnum.A.getErrorMessage());
                            mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
                            mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
                            inValidList.add(mbImportExcelRecordDetailLog);
                            continue;
                        }
                        // 数据权限校验
                        List<String> orgIds = (List<String>) RequestContext.getCurrentContext().getContextParams(DATA_PERMISSION_ORG_ID_LIST);
                        if(CollectionUtils.isNotEmpty(orgIds) && !orgIds.contains(o.getBasicInfo().getOrgId())){
                            MbImportExcelRecordDetailLog mbImportExcelRecordDetailLog = new MbImportExcelRecordDetailLog();
                            mbImportExcelRecordDetailLog.setLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setMainLineNo(o.getLineNo());
                            mbImportExcelRecordDetailLog.setStatus("F");
                            mbImportExcelRecordDetailLog.setMessage(OrganizationResponseCodeEnum.UID_DONT_PERMISSION.message());
                            mbImportExcelRecordDetailLog.setDatachangeCreatetime(new Date());
                            mbImportExcelRecordDetailLog.setDatachangeLasttime(new Date());
                            inValidList.add(mbImportExcelRecordDetailLog);
                            continue;
                        }
                        multiTenantSyncEmpAndOrgProducer.sendSyncOrgMsg(o, notifyUrl, MessageBizTypeEnum.SYNC_ORGANIZATION_UPDATE, baseUserInfo, inValidList, recordId);
                    }

                }catch(Exception e){
                    errorFlag = true;
                    log.error(e.getMessage());
                }
            }
            if (CollectionUtils.isNotEmpty(inValidList)){
                inValidList.forEach(inValidItem -> inValidItem.setRecordId(recordId));
                mbImportExcelRecordService.batchInsertRecordDetailLog(inValidList);
                MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, false, MetricService.ASYNC);
                // 有参数校验不通过
                return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_Excel_Param_Error, false);
            }
            if (errorFlag){
                return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_Excel_Param_Error, false);
            }
            log.info("插入记录：{}", JsonUtils.toJsonString(inValidList));
            MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, true, MetricService.ASYNC);
            return setResponse(ServiceErrorEnum.Success, true);
        } catch (Exception ex) {
            log.error("导入组织excel失败", ex);
            MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_ORG, false, MetricService.ASYNC);
            return setResponse(ServiceErrorEnum.SyncHumanResources_SyncOrgInfo_ErrorRequest_Failure, false);
        }
    }


    /**
     * 人员信息同步接口,/corpApi/openapi/datasync/syncEmployeeInfo
     * @param request
     * @return
     */

    @RequestMapping("/syncOrgEmployeeByOpenApi")
    public SyncOrgEmployeeRsp syncOrgEmployee(@RequestBody SyncOrgEmployeeReq request){
        log.info("人员信息同步接口,/corpApi/openapi/datasync/syncEmployeeInfo,request:{}",JsonUtils.toJsonString(request));
        ObjectStringTrimUtils.allFieldRemoveWarp(request);
        log.info("人员信息同步接口,/corpApi/openapi/datasync/syncEmployeeInfo,request after:{}",JsonUtils.toJsonString(request));

        return syncOrgEmployeeService.process(request);
    }

    /**
     * 同步员工-------》外部调用进来---------》从openApi转进来
     *
     * @param employeeRequest
     * @return
     */
    @RequestMapping("/syncemployeeinfo")
    public SyncHumanResourcesResponseEntity syncEmployeeInfo(@RequestBody @Valid SyncEmployeeRequestEntity employeeRequest, BindingResult bindingResult) {
        SyncHumanResourcesResponseEntity response = new SyncHumanResourcesResponseEntity();
        response.setResult(false);

        // 验证参数正确性
        String bindError = ValidUtils.getErrorStr(bindingResult);
        if (StringUtils.isNotBlank(bindError)) {
            bindError = bindError.length() > 500 ? String.format("%s...等%d个错误", bindError.substring(0, 500), bindingResult.getErrorCount()) : bindError;
            setResponse(ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorRequest_Failure, false);
            response.setMessage(bindError);
            return response;
        }

        return sendEmpMsg(response, employeeRequest.getEmployeeInfoList(), employeeRequest.getNotifyUrl(), employeeRequest.getRecordId());
    }

    /**
     * 发送员工mq
     *
     * @param response
     * @param empList
     * @param notifyUrl
     * @return
     */
    private SyncHumanResourcesResponseEntity sendEmpMsg(SyncHumanResourcesResponseEntity response, List<SyncEmployeeRequestEntity.SyncEmployeeInfoEntity> empList, String notifyUrl, Long recordId) {

        // 去除list中的null
        List<SyncEmployeeRequestEntity.SyncEmployeeInfoEntity> employeeList = Optional.ofNullable(empList).orElse(new ArrayList<>()).stream().filter(Objects::nonNull).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(employeeList)) {
            return setResponse(ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorRequest_Failure, false);
        }
        employeeList.forEach(org -> {
            if (CollectionUtils.isNotEmpty(org.getCardTypeList())) {
                org.getCardTypeList().removeIf(Objects::isNull);
            }
            if (CollectionUtils.isNotEmpty(org.getOrgRelation())) {
                org.getOrgRelation().removeIf(Objects::isNull);
            }
        });

        try {
            // 验证存在于系统中的人员
            List<String> uids = employeeList.stream()
                    .filter(o -> BooleanUtils.isNotTrue(o.getIsDelete()) && o.getBasicInfo() != null && StringUtils.isNotBlank(o.getBasicInfo().getUid()))
                    .map(o -> o.getBasicInfo().getUid()).distinct().collect(Collectors.toList());
            List<MbOrgEmployeeInfo> mbOrgEmployeeInfos = Optional.ofNullable(organizationEmployeeService.listByUids(uids)).orElse(new ArrayList<>());
            Set<String> uidsInSystem = mbOrgEmployeeInfos.stream().filter(o -> o != null && StringUtils.isNotBlank(o.getUid()))
                    .map(MbOrgEmployeeInfo::getUid).collect(Collectors.toSet());

            // 推送消息
            for (SyncEmployeeRequestEntity.SyncEmployeeInfoEntity e : employeeList) {

                if (BooleanUtils.isTrue(e.getIsDelete())) {
                    e.setMessageBizTypeEnum(MessageBizTypeEnum.SYNC_EMPLOYEE_DELETE);
                } else if (uidsInSystem.contains(e.getBasicInfo().getUid())) {
                    e.setMessageBizTypeEnum(MessageBizTypeEnum.SYNC_EMPLOYEE_UPDATE);
                } else {
                    e.setMessageBizTypeEnum(MessageBizTypeEnum.SYNC_EMPLOYEE_ADD);
                }
            }

            SyncEmployeeRequestEntity employeeInfo = new SyncEmployeeRequestEntity();
            employeeInfo.setNotifyUrl(notifyUrl);
            employeeInfo.setRecordId(recordId);
            employeeInfo.setEmployeeInfoList(new ArrayList<>());
            employeeInfo.getEmployeeInfoList().addAll(employeeList);
            multiTenantSyncEmpAndOrgProducer.sendSyncEmployeeMsg(employeeInfo);
            return setResponse(ServiceErrorEnum.Success, true);
        } catch (Exception ex) {
            log.error("SyncHumanResourcesController.syncOrginfo", ex);
            response.setErrorCode("-999");
            response.setMessage(ex.getMessage());
            return response;
        }
    }

    /**
     * 设置response结果
     */
    private SyncHumanResourcesResponseEntity setResponse(ServiceErrorEnum serviceError, Boolean result) {
        SyncHumanResourcesResponseEntity response = new SyncHumanResourcesResponseEntity();
        response.setErrorCode(serviceError.getErrorCode());
        response.setMessage(serviceError.getErrorMessage());
        response.setResult(result);
        return response;
    }

    @RequestMapping("downloadTemplate")
    public JSONResult<String> downloadTemplate(@RequestParam String templateName, HttpServletResponse response) {
        if (StringUtils.isEmpty(templateName)) {
            return JSONResult.errorMsg("模板名称为空");
        }
        return excelUtils.downloadTemplate(templateName, response);
    }


    @RequestMapping("searchImportExcelRecordByPage")
    public JSONResult<Page> searchImportExcelRecordByPage(@RequestBody SearchMbImportExcelRecordRequestVo requestVo, BaseUserInfo baseUserInfo) throws Exception {
        if (requestVo == null) {
            return null;
        }
        String corpId = null;
        if (!baseUserInfo.getBgUser()) {
            corpId = baseUserInfo.getCorpId();
        }
        return mbImportExcelRecordService.searchImportExcelRecordByPage(requestVo, corpId);
    }

    @RequestMapping("downloadImportExcel")
    public void downloadImportExcel(@RequestBody SearchMbImportExcelRecordDetailLogRequestVo requestVo, HttpServletResponse response) {
        if (requestVo == null) {
            return ;
        }
        mbImportExcelRecordService.downloadImportExcel(requestVo.getRecordId(),response);
    }


    @RequestMapping("searchImportExcelRecordDetailLogByPage")
    public JSONResult<Page> searchImportExcelRecordDetailLogByPage(@RequestBody SearchMbImportExcelRecordDetailLogRequestVo requestVo) throws Exception {
        if (requestVo == null) {
            return null;
        }
        return mbImportExcelRecordService.searchImportExcelRecordDetailLogByPage(requestVo.getPageNum(), requestVo.getPageSize(), requestVo.getRecordId());
    }

    /**
     * syncTpye -- "add" "update" 同步类型 新增/更新
     * checkOrgChange  true:校验组织机构有没有变动, false/null：不校验组织机构有没有变动
     */
    @PostMapping("/syncEmployeeInfoByExcelNew")
    public JSONResult syncEmployeeInfoByExcelNew(@RequestParam("file") MultipartFile file,
                                                 @RequestParam String defaultOrgId, BaseUserInfo baseUserInfo,
                                                 @RequestParam String syncTpye,
                                                 @RequestParam(name = "checkOrgChange", required = false)  Boolean checkOrgChange) throws IOException {
        StringBuilder logContext = new StringBuilder();
        try {
            if (StringUtils.isBlank(defaultOrgId)) {
                return JSONResult.errorMsg("请先选择左侧织列表组再进行人员导入");
            }

            syncEmployeeNewService.handleEmployImport(file,baseUserInfo,defaultOrgId,syncTpye,checkOrgChange);

           /* List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList = new ArrayList<>();
            XSSFWorkbook sheets = new XSSFWorkbook(file.getInputStream());
            //获取员工数据
            XSSFSheet sheetOrg = sheets.getSheet("员工");
            List<EmployeeInfoExcelColumnVO> employeeInfo = excelUtils.getBeanListFromExcelTwo(sheetOrg, EmployeeInfoExcelColumnVO.class);
            LogSplicingUtils.addLogContext(logContext, "员工信息: %s", JsonUtils.toJsonString(employeeInfo));

            if (CollectionUtils.isEmpty(employeeInfo)) {
                return JSONResult.errorMsg("上传表格无可用人员数据");
            }

            // FIXME 暂时校验用户手机号是否不为空。后续需要等黄超的最新代码上线后，再与黄超的最新代码合并
            employeeInfo.forEach(user -> {
                if (StringUtils.isBlank(user.getMobilePhone())) {
                    failInfoList.add(new SyncEmployeeCallBackRequestEntity.FailInfo(user.getLineNo(), SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(), SyncEmployeeInfoBo.SheetEnum.EMP.getName(), user.getLineNo(), "手机号码为空"));
                }
            });

            //获取证件数据
            XSSFSheet sheetDelivery = sheets.getSheet("证件");
            List<EmployeeCardTypeInfoColumnVO> empCardType = excelUtils.getBeanListFromExcel(sheetDelivery, EmployeeCardTypeInfoColumnVO.class);
            LogSplicingUtils.addLogContext(logContext, "证件信息: %s", JsonUtils.toJsonString(empCardType));

            employeeInfo.forEach(StrUtils::fieldRemoveWarp);
            empCardType.forEach(StrUtils::fieldRemoveWarp);

            //将证件信息——>Map
            Map<String, List<EmployeeCardTypeInfoColumnVO>> empCardMap = empCardType.stream().
                    filter(item -> Objects.nonNull(item) && StringUtils.isNotBlank(item.getUid())).collect(Collectors.groupingBy(item -> item.getUid()));
            LogSplicingUtils.addLogContext(logContext, "证件信息Map: %s", JsonUtils.toJsonString(empCardMap));

            confirmGenderAndBirthDay(empCardMap, employeeInfo);
            //导入人员总数
            int totalCount = employeeInfo.size();
            List<SyncEmployeeInfoBo> empList = new ArrayList<>();
            //将员工绑定证件
            for (EmployeeInfoExcelColumnVO item : employeeInfo) {
                convertCountry(item);
                checkRequestParams(failInfoList, item);
                SyncEmployeeInfoBo employeeInfoBo = null;
                try {
                    employeeInfoBo = buildEmployeeInfoBo(empCardMap, item);
                    empList.add(employeeInfoBo);
                } catch (Exception e){
                    failInfoList.add(new SyncEmployeeCallBackRequestEntity.FailInfo(item.getLineNo(),SyncEmployeeInfoBo.SheetEnum.CARD.getIndex(),SyncEmployeeInfoBo.SheetEnum.CARD.getName(),item.getLineNo(), e.getMessage()));
                }
            }
            LogSplicingUtils.addLogContext(logContext, "组装后数据：%s", JsonUtils.toJsonString(empList));


            String fileUrl = basicOssClientLoader.putPrivateObject(file);
            syncEmployeeNewService.syncEmployeeInfo(empList, baseUserInfo, defaultOrgId, file.getOriginalFilename(),fileUrl, failInfoList, totalCount,syncTpye,checkOrgChange);*/
        } catch (Exception e) {
            log.info("发生异常：", e);
            MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_EMPLOYEE,false,MetricService.SYNC);
            if (e instanceof CorpBusinessException){
                throw new CorpBusinessException(((CorpBusinessException) e).getResultCode(), ((CorpBusinessException) e).getMsg());
            }
            return JSONResult.errorMsg("电子表格格式错误，请重新导入！");
        } finally {
            log.info("员工导入日志：{}", logContext);
        }
        MetricService.metricOrgOrEmployeeCounter(MetricService.ORGANIZATION_MANAGE_IMPORT_EMPLOYEE,true,MetricService.SYNC);
        return JSONResult.ok();
    }


    private void convertCountry(EmployeeInfoExcelColumnVO item){
        NationalityEnum nation = NationalityEnum.getByDesc(Optional.ofNullable(item.getNationality()).orElse(NationalityEnum.CN.getCode()));
        if(nation !=null){
            item.setNationality(nation.getCode());
        }else {
            item.setNationality(NationalityEnum.CN.getCode());
        }
    }

    private void checkRequestParams(List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList, EmployeeInfoExcelColumnVO item) throws IllegalAccessException {
        boolean exists = false;
        Field[] declaredField = item.getClass().getDeclaredFields();
        for (Field field:declaredField){
            field.setAccessible(true);
            Object obj = field.get(item);
            if (Objects.nonNull(obj)){
                exists = true;
            }
        }
        if (!exists){
            return ;
        }
        if (StringUtils.isBlank(item.getUid())) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "员工编号为空"));
        }
        if (item.getUid().length() > 50) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "员工编号长度大于50"));
        }
        if (StringUtils.isNotBlank(item.getPostId()) && !item.getPostId().matches("^[0-9]*$")) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "员工职级ID必须为整数"));
        }
        if (StringUtils.isNotBlank(item.getNationality()) && Objects.isNull(NationalityEnum.getByCode(item.getNationality()))) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "国籍的国家二字码错误"));
        }
        if (StringUtils.isNotBlank(item.getGender()) && Objects.isNull(GenderEnum.getByName(item.getGender()))) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "性别错误"));
        }
        if (StringUtils.isNotBlank(item.getCountryCode()) && Objects.isNull(PhoneCountryCodeEnum.getByDescAndCountryCode(item.getCountryCode()))) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "手机国家码错误"));
        }
        if ((StringUtils.isBlank(item.getCountryCode()) || PhoneCountryCodeEnum.CN.getCountryCode().equals(item.getCountryCode())) &&
                (StringUtils.isBlank(item.getMobilePhone()) || item.getMobilePhone().length() > 11)) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),item.getLineNo(),item.getLineNo(), "手机号码填写错误"));
        }
    }

    private  SyncEmployeeInfoBo buildEmployeeInfoBo(Map<String, List<EmployeeCardTypeInfoColumnVO>> empCardMap, EmployeeInfoExcelColumnVO item) {
        SyncEmployeeInfoBo employeeInfoBo = new SyncEmployeeInfoBo();
        employeeInfoBo.setLineNo(item.getLineNo());
        employeeInfoBo.setIsDelete(false);
        employeeInfoBo.setUid(item.getUid());
        employeeInfoBo.setName(item.getName());
        employeeInfoBo.setLastName(item.getLastName());
        employeeInfoBo.setFirstName(item.getFirstName());
        if (StringUtils.isEmpty(item.getCountryCode())) {
            employeeInfoBo.setCountryCode(PhoneCountryCodeEnum.CN.getCountryCode());
        } else {
            employeeInfoBo.setCountryCode(item.getCountryCode().startsWith("+") ? item.getCountryCode() : "+" + item.getCountryCode());
        }
        employeeInfoBo.setMobilePhone(item.getMobilePhone());
        // employeeInfoBo.setPassword(item.getPassword());
        employeeInfoBo.setBirthday(item.getBirthday());
        employeeInfoBo.setGender(F.getDesc().equals(item.getGender()) ? F.getCode() : M.getCode());
        employeeInfoBo.setEmail(item.getEmail());
        NationalityEnum nationalityEnum = Optional.ofNullable(NationalityEnum.getByCode(item.getNationality())).orElse(NationalityEnum.CN);
        employeeInfoBo.setNationality(nationalityEnum.getCode());
        employeeInfoBo.setCreditCardNumbers(null);
        employeeInfoBo.setBusinessCode(item.getBusinessCode());
        employeeInfoBo.setPostName(item.getPostName());
        employeeInfoBo.setPostId(StringUtils.isNotBlank(item.getPostId()) ? Long.valueOf(item.getPostId()) : null);

        List<SyncEmployeeInfoBo.SyncEmployeeCardInfoBo> idCardInfoBoList = new ArrayList<>();
        List<EmployeeCardTypeInfoColumnVO> idCardInfoList = empCardMap.get(item.getUid());
        if (CollectionUtils.isNotEmpty(idCardInfoList)) {
            for (EmployeeCardTypeInfoColumnVO carInfo : idCardInfoList) {
                SyncEmployeeInfoBo.SyncEmployeeCardInfoBo cardInfoBo = new SyncEmployeeInfoBo.SyncEmployeeCardInfoBo();
                cardInfoBo.setLineNo(carInfo.getLineNo());
                cardInfoBo.setCardType(carInfo.getCardType());
                cardInfoBo.setCardNo(carInfo.getCardNo());
                cardInfoBo.setTimeLimit(carInfo.getTimeLimit());
                cardInfoBo.setUid(carInfo.getUid());
                cardInfoBo.setPlaceOfIssue(carInfo.getPlaceOfIssue());
                idCardInfoBoList.add(cardInfoBo);
            }
        }
        employeeInfoBo.setCardInfoList(idCardInfoBoList);
        employeeInfoBo.setRoleName(item.getRoleName());
        employeeInfoBo.setEmployeeType(ApplyTripEmployeeEnum.getCodeByName(item.getEmployeeType()));
        employeeInfoBo.setManageUid(item.getManageUid());
        employeeInfoBo.setJobCode(item.getJobCode());
        employeeInfoBo.setJobName(item.getJobName());
        return employeeInfoBo;
    }

    public SyncEmployeeCallBackRequestEntity.FailInfo addFaildInfo(Integer sheetIndex,String sheetName,String mainLineNo, String lineNo, String message) {
        SyncEmployeeCallBackRequestEntity.FailInfo failInfo = new SyncEmployeeCallBackRequestEntity.FailInfo();
        failInfo.setSheetIndex(sheetIndex);
        failInfo.setSheetName(sheetName);
        failInfo.setMainLineNo(mainLineNo);
        failInfo.setLineNo(lineNo);
        failInfo.setFailReason(message);
        return failInfo;
    }

    @PostMapping("/downloadEmployeeInfo")
    public void downloadEmployeeInfo(@RequestBody GetOrgTreeRequest request, HttpServletResponse response) {
        // 构建orgId查询出员工信息
        List<String> orgIds = new ArrayList<>();
        if (request.getOrgId() != null) {
            orgIds.add(request.getOrgId());
        }
        if (request.getOrgIds() != null) {
            orgIds.addAll(request.getOrgIds());
        }
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = syncEmployeeNewService.findDownloadEmployeeInfo(orgIds);

        // 查询出员工证件信息
        List<String> uidList = orgEmployeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        List<MbOrgUserIdcard> userIdCards = syncEmployeeNewService.findOrgUserIdCard(uidList);

        // 构建员工信息响应
        List<EmployeeDownloadResponseVo> employeeDownloadResponseVoList = orgEmployeeInfoList.stream()
                .map(this::buildEmployeeDownLoadResponseVo)
                .collect(Collectors.toList());
        // 构建员工证件响应
        List<EmployeeDownloadUserIdCardResponseVo> cardResponseVos = userIdCards.stream()
                .map(this::buildUserIdCard)
                .collect(Collectors.toList());

        // 员工岗位信息
        Map<String, JobDo> uidJobMap = jobService.getUidJobMap(uidList);
        log.info("员工岗位信息：{}", JsonUtils.toJsonString(uidJobMap));
        employeeDownloadResponseVoList.forEach(item -> {
            JobDo jobDo = uidJobMap.get(item.getUid());
            if (jobDo != null) {
                item.setJobCode(jobDo.getCode());
                item.setJobName(jobDo.getName());
            }
        });

        EmployeeDownloadTemplate template = new EmployeeDownloadTemplate();
        template.setEmployeeDownloadResponseVoList(employeeDownloadResponseVoList);
        template.setEmployeeDownloadUserIdCardResponseVoList(cardResponseVos);
        template.setFileName("人员信息");
        excelUtils.downloadExcelEmployee(response, template);
    }


    @PostMapping("/downloadEmployeeInfoForUpdate")
    public void downloadEmployeeInfoForUpdate(HttpServletResponse response,@RequestBody @Valid ListEmployeeInOrgRequest listEmployeeInOrgRequest) {
        // 构建orgId查询出员工信息
        String orgId = listEmployeeInOrgRequest.getOrgId();
        String condition = listEmployeeInOrgRequest.getStaffInfo();
        Integer pageNum = listEmployeeInOrgRequest.getIndex();
        Integer pageSize = listEmployeeInOrgRequest.getPageSize();

        ListEmployeeInOrgVO listEmployeeInOrgVO = new ListEmployeeInOrgVO();
        listEmployeeInOrgVO.setOrgId(orgId);
        listEmployeeInOrgVO.setStaffInfo(condition);
        listEmployeeInOrgVO.setIndex(pageNum);
        listEmployeeInOrgVO.setPageSize(pageSize);
        listEmployeeInOrgVO.setJobId(listEmployeeInOrgRequest.getJobId());

        Pair< List<MbOrgEmployeeInfo>,Long> res = organizationInfoService.listEmployeeInOrg(listEmployeeInOrgVO);
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = res.getLeft();

        // 查询出员工证件信息
        List<String> uidList = orgEmployeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        List<MbOrgUserIdcard> userIdCards = syncEmployeeNewService.findOrgUserIdCard(uidList);

        // 构建员工信息响应
        List<EmployeeInfoExcelColumnVO> employeeDownloadResponseVoList = orgEmployeeInfoList.stream()
                .map(this::buildEmployeeDownLoadResponseVoForUpdate)
                .collect(Collectors.toList());

        // 添加岗位信息
        fillJobInfo(employeeDownloadResponseVoList);

        // 构建员工证件响应
        List<EmployeeDownloadUserIdCardResponseVo> cardResponseVos = userIdCards.stream()
                .map(this::buildUserIdCardForUpdate)
                .collect(Collectors.toList());

        EmployeeDownloadTemplate template = new EmployeeDownloadTemplate();
        template.setEmployeeInfoExcelColumnVOList(employeeDownloadResponseVoList);
        template.setEmployeeDownloadUserIdCardResponseVoList(cardResponseVos);
        template.setFileName("人员信息");
        excelUtils.downloadExcelEmployeeWithLock(response, template);
    }

    /**
     * 补充岗位信息
     */
    private void fillJobInfo(List<EmployeeInfoExcelColumnVO> employeeDownloadResponseVoList) {
        if (CollectionUtils.isEmpty(employeeDownloadResponseVoList)) {
            return;
        }
        // 获取岗位信息
        Map<String, JobDo> uidJobMap = jobService.getUidJobMap(employeeDownloadResponseVoList.stream().map(EmployeeInfoExcelColumnVO::getUid).collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(uidJobMap)) {
            return;
        }
        // 填充岗位信息
        employeeDownloadResponseVoList.forEach(item -> {
            JobDo jobDo = uidJobMap.get(item.getUid());
            if (jobDo != null) {
                item.setJobName(jobDo.getName());
                item.setJobCode(jobDo.getCode());
            }
        });
    }

    /**
     * 构建员工信息响应
     */
    private EmployeeInfoExcelColumnVO buildEmployeeDownLoadResponseVoForUpdate(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        EmployeeInfoExcelColumnVO employeeDownloadResponseVo = new EmployeeInfoExcelColumnVO();
        employeeDownloadResponseVo.setBirthday(DateUtil.dateToYMD(mbOrgEmployeeInfo.getBirthday()));
        employeeDownloadResponseVo.setEmail(mbOrgEmployeeInfo.getEmail());
        employeeDownloadResponseVo.setGender(Null.or(mbOrgEmployeeInfo.getGender(), gender -> Null.or(GenderEnum.getByCode(gender), GenderEnum::getDesc, null), null));
        employeeDownloadResponseVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
        employeeDownloadResponseVo.setPostName(mbOrgEmployeeInfo.getPostName());
        employeeDownloadResponseVo.setPostId(mbOrgEmployeeInfo.getPostId() !=null?String.valueOf(mbOrgEmployeeInfo.getPostId()):null);
        employeeDownloadResponseVo.setUid(mbOrgEmployeeInfo.getUid());
        MbOrgInfo orgInfo = organizationInfoService.findByOrgId(mbOrgEmployeeInfo.getOrgId());
        employeeDownloadResponseVo.setBusinessCode(orgInfo.getBusinessCode());
        employeeDownloadResponseVo.setName(mbOrgEmployeeInfo.getName());
        employeeDownloadResponseVo.setCountryCode(PhoneCountryCodeEnum.getByCountryCode(mbOrgEmployeeInfo.getAreaCode()).getDesc() + PhoneCountryCodeEnum.getByCountryCode(mbOrgEmployeeInfo.getAreaCode()).getCountryCode());
        if(mbOrgEmployeeInfo.getNationName()!= null){
            employeeDownloadResponseVo.setNationality(mbOrgEmployeeInfo.getNationName());
        }else {
            employeeDownloadResponseVo.setNationality(replaceNationalityForUpdate(mbOrgEmployeeInfo.getNationality()));
        }

        employeeDownloadResponseVo.setRoleName(mbOrgEmployeeInfo.getRoleName());
        employeeDownloadResponseVo.setManageUid(mbOrgEmployeeInfo.getManageUid());

        employeeDownloadResponseVo.setLastName(mbOrgEmployeeInfo.getFirstEnName());
        employeeDownloadResponseVo.setFirstName(mbOrgEmployeeInfo.getLastEnName());

        employeeDownloadResponseVo.setEmployeeType((ApplyTripEmployeeEnum.getNameByCode(mbOrgEmployeeInfo.getEmployeeType())));

        List<MbRole> roleInfoList = roleService.findByUidAndOrgId(mbOrgEmployeeInfo.getUid(), mbOrgEmployeeInfo.getOrgId());
        if (CollectionUtils.isNotEmpty(roleInfoList)) {
            employeeDownloadResponseVo.setRoleName(roleInfoList.get(0).getName());
        }
        if(ObjectUtil.isNotNull(mbOrgEmployeeInfo.getPostId())){
            MbPostInfo mbPostInfo = postService.find(mbOrgEmployeeInfo.getPostId());
            if(mbPostInfo!=null){
                employeeDownloadResponseVo.setPostName(mbPostInfo.getName());
                employeeDownloadResponseVo.setPostCode(mbPostInfo.getCode());
            }
        }
        return employeeDownloadResponseVo;
    }

    /**
     * 构建员工证件响应
     */
    private EmployeeDownloadUserIdCardResponseVo buildUserIdCard(MbOrgUserIdcard userIdCard) {
        EmployeeDownloadUserIdCardResponseVo vo = new EmployeeDownloadUserIdCardResponseVo();
        vo.setUid(userIdCard.getEmployeeUid());
        vo.setTimeLimit(DateUtil.dateToYMD_HM(userIdCard.getTimeLimit()));
        vo.setCardType(CardEnum.getByType(String.valueOf(userIdCard.getCardType())).getName());
        vo.setCardNo(userIdCard.getCardNo());
        vo.setPlaceOfIssue(userIdCard.getPlaceOfIssue());
        return vo;
    }

    /**
     * 构建员工证件响应
     */
    private EmployeeDownloadUserIdCardResponseVo buildUserIdCardForUpdate(MbOrgUserIdcard userIdCard) {
        EmployeeDownloadUserIdCardResponseVo vo = new EmployeeDownloadUserIdCardResponseVo();
        vo.setUid(userIdCard.getEmployeeUid());
        vo.setTimeLimit(DateUtil.dateToYMD_HM(userIdCard.getTimeLimit()));
        vo.setCardType(CardEnum.getByType(String.valueOf(userIdCard.getCardType())).getName());
        vo.setCardNo(userIdCard.getCardNo());
        vo.setPlaceOfIssue(replaceNationalityForUpdate(userIdCard.getPlaceOfIssue()));
        return vo;
    }

    /**
     * 构建员工信息响应
     */
    private EmployeeDownloadResponseVo buildEmployeeDownLoadResponseVo(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        EmployeeDownloadResponseVo employeeDownloadResponseVo = new EmployeeDownloadResponseVo();
        employeeDownloadResponseVo.setEmpId(mbOrgEmployeeInfo.getId());
        employeeDownloadResponseVo.setBirthday(DateUtil.dateToYMD(mbOrgEmployeeInfo.getBirthday()));
        employeeDownloadResponseVo.setCompanyName(EncryptUtils.sm4Decrypt(mbOrgEmployeeInfo.getCompanyName()));
        employeeDownloadResponseVo.setEmail(mbOrgEmployeeInfo.getEmail());
        employeeDownloadResponseVo.setFirstEnName(mbOrgEmployeeInfo.getFirstEnName());
        employeeDownloadResponseVo.setLastEnName(mbOrgEmployeeInfo.getLastEnName());
        employeeDownloadResponseVo.setGender(Null.or(mbOrgEmployeeInfo.getGender(), gender -> Null.or(GenderEnum.getByCode(gender), t -> t.getDesc(), null), null));
        employeeDownloadResponseVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
        employeeDownloadResponseVo.setOrgName(EncryptUtils.sm4Decrypt(mbOrgEmployeeInfo.getOrgName()));

        employeeDownloadResponseVo.setPostId(mbOrgEmployeeInfo.getPostId());
        employeeDownloadResponseVo.setUid(mbOrgEmployeeInfo.getUid());
        employeeDownloadResponseVo.setName(mbOrgEmployeeInfo.getName());
        employeeDownloadResponseVo.setCountryCode(mbOrgEmployeeInfo.getAreaCode());
        employeeDownloadResponseVo.setNationality(replaceNationality(mbOrgEmployeeInfo.getNationality()));
        employeeDownloadResponseVo.setOrgId(mbOrgEmployeeInfo.getOrgId());
        employeeDownloadResponseVo.setRoleName(mbOrgEmployeeInfo.getRoleName());
        employeeDownloadResponseVo
            .setEmployeeDesc(Optional
                .ofNullable(ApplyTripEmployeeEnum.getNameByCode(mbOrgEmployeeInfo.getEmployeeType()))
                .orElse(ApplyTripEmployeeEnum.EMPLOYEE.getName()));
        employeeDownloadResponseVo.setManageUid(mbOrgEmployeeInfo.getManageUid());

        if(ObjectUtil.isNotNull(mbOrgEmployeeInfo.getPostId())){
            MbPostInfo mbPostInfo = postService.find(mbOrgEmployeeInfo.getPostId());
            if(mbPostInfo!=null){
                employeeDownloadResponseVo.setPostName(mbPostInfo.getName());
            }
        }
        return employeeDownloadResponseVo;
    }

    private String replaceNationality(String nationality) {
        if (StringUtils.isNotBlank(nationality)) {
            String code = nationality.split("\\|")[0];
            NationalityEnum byCode = NationalityEnum.getByCode(code);
            return Objects.isNull(byCode) ? NationalityEnum.CN.getCode() : byCode.getCode();
        }
        return NationalityEnum.CN.getCode();
    }

    private String replaceNationalityForUpdate(String nationality) {
        if (StringUtils.isNotBlank(nationality)) {
            String[] split = nationality.split("\\|");
            if (split.length <= 1) {
                return NationalityEnum.CN.getDesc();
            }
            String desc = split[1];
            NationalityEnum byCode = NationalityEnum.getByDesc(desc);
            return Objects.isNull(byCode) ? NationalityEnum.CN.getDesc() : byCode.getDesc();
        }
        return NationalityEnum.CN.getDesc();
    }

    @RequestMapping("/downloadOrgInfo")
    public void downloadOrgInfo(@RequestBody GetOrgTreeRequest request, HttpServletResponse response) {
        //组织信息
        List<OrgInfoDownloadResponseVo> orgInfoDownloadResponseVoList = new ArrayList<>();
        //发票信息
        List<OrgInvoiceInfoDownloadResponseVo> orgInvoiceInfoDownloadResponseVoList = new ArrayList<>();
        //配送地址
        List<OrgDeliveryInfoDownloadResponseVo> orgDeliveryInfoDownloadResponseVoList = new ArrayList<>();
        //岗位信息
        List<OrgPostInfoDownloadResponseVo> orgPostInfoDownloadResponseVoList = new ArrayList<>();

        List<String> stringList = organizationInfoService.listAllDepartmentByOrgId(request);
        for (String oid : stringList) {
            //查询组织信息
            MbOrgInfo orgInfo = organizationInfoService.findByOrgId(oid);
            if (orgInfo.getId() < 0) {
                continue;
            }

            OrgInfoDownloadResponseVo orgInfoDownloadResponseVo = new OrgInfoDownloadResponseVo();
            orgInfoDownloadResponseVo.setIsDelete("否");
            orgInfoDownloadResponseVo.setOrgId(orgInfo.getOrgId());
            orgInfoDownloadResponseVo.setType(Objects.equals(OrgTypeEnum.C.getCode(), orgInfo.getOrgType()) ? OrgTypeEnum.C.getDesc() : OrgTypeEnum.D.getDesc());
            orgInfoDownloadResponseVo.setParentBusinessCode(orgInfo.getParentBusinessCode());
            orgInfoDownloadResponseVo.setIsActive(Objects.equals("T", orgInfo.getValid()) ? "是" : "否");
            orgInfoDownloadResponseVo.setContactName(orgInfo.getContactName());
            orgInfoDownloadResponseVo.setContactEmail(orgInfo.getContactEmail());
            orgInfoDownloadResponseVo.setContactCountryCode(orgInfo.getContactAreaCode());
            orgInfoDownloadResponseVo.setContactPhone(orgInfo.getContactPhone());
            orgInfoDownloadResponseVo.setName(orgInfo.getName());
            orgInfoDownloadResponseVo.setBusinessCode(orgInfo.getBusinessCode());
            orgInfoDownloadResponseVoList.add(orgInfoDownloadResponseVo);

            //查询发票信息
            List<MbCommonInvoiceInfo> mbCommonInvoiceInfos = commonInvoiceInfoService.listByOrgIdReal(oid);
            mbCommonInvoiceInfos.stream().forEach(item -> {
                OrgInvoiceInfoDownloadResponseVo orgInvoiceInfoDownloadResponseVo = new OrgInvoiceInfoDownloadResponseVo();
                orgInvoiceInfoDownloadResponseVo.setAccountBank(item.getAccountBank());
                orgInvoiceInfoDownloadResponseVo.setAccountCardNo(item.getAccountCardNo());
                orgInvoiceInfoDownloadResponseVo.setOrgId(item.getOrgId());
                orgInvoiceInfoDownloadResponseVo.setTaxId(item.getTaxId());
                orgInvoiceInfoDownloadResponseVo.setInvoiceTitle(item.getInvoiceTitle());
                orgInvoiceInfoDownloadResponseVo.setCorporationPhone(item.getCorporationPhone());
                orgInvoiceInfoDownloadResponseVo.setCorporationAddress(item.getCorporationAddress());
                orgInvoiceInfoDownloadResponseVo.setBusinessCode(orgInfo.getBusinessCode());
                orgInvoiceInfoDownloadResponseVoList.add(orgInvoiceInfoDownloadResponseVo);
            });

            //查询配送地址
            List<MbExpressAddress> mbExpressAddresses = expressAddressService.listByOrgId(oid);
            if (OrgTypeEnum.D.getCode().equals(orgInfo.getOrgType()) && CollectionUtils.isEmpty(mbExpressAddresses)) {
                MbOrgInfo corpOrgInfo = iOrganizationInfoService.findRecentCompanyIdByOrgId(oid);
                mbExpressAddresses = expressAddressService.listByOrgId(corpOrgInfo.getOrgId());
            }
            mbExpressAddresses.stream().forEach(item -> {
                OrgDeliveryInfoDownloadResponseVo orgDeliveryInfoDownloadResponseVo = new OrgDeliveryInfoDownloadResponseVo();
                orgDeliveryInfoDownloadResponseVo.setOrgId(oid);
                orgDeliveryInfoDownloadResponseVo.setProvinceName(item.getProvinceName());
                orgDeliveryInfoDownloadResponseVo.setCityName(item.getCityName());
                orgDeliveryInfoDownloadResponseVo.setDistrictName(item.getDistrictName());
                orgDeliveryInfoDownloadResponseVo.setAddress(item.getAddress());
                orgDeliveryInfoDownloadResponseVo.setRecipientName(item.getRecipientName());
                orgDeliveryInfoDownloadResponseVo.setRecipientCountryCode(item.getCountryCode());
                orgDeliveryInfoDownloadResponseVo.setRecipientPhone(item.getRecipientPhone());
                orgDeliveryInfoDownloadResponseVo.setIsDefault(CommonEnum.Y.getCode().equals(item.getIsDefault()) ? CommonEnum.Y.getDesc() : CommonEnum.N.getDesc());
                orgDeliveryInfoDownloadResponseVo.setBusinessCode(orgInfo.getBusinessCode());
                orgDeliveryInfoDownloadResponseVoList.add(orgDeliveryInfoDownloadResponseVo);
            });

            //查询岗位信息
            List<MbPostInfo> mbPostInfos = postService.listByOrgId(oid);
            mbPostInfos.stream().forEach(item -> {
                OrgPostInfoDownloadResponseVo orgPostInfoDownloadResponseVo = new OrgPostInfoDownloadResponseVo();
                orgPostInfoDownloadResponseVo.setOrgId(item.getOrgId());
                orgPostInfoDownloadResponseVo.setPostName(item.getName());
                orgPostInfoDownloadResponseVo.setBusinessCode(orgInfo.getBusinessCode());
                orgPostInfoDownloadResponseVoList.add(orgPostInfoDownloadResponseVo);
            });

        }

        OrgInfoDownloadTemplate template = new OrgInfoDownloadTemplate();
        template.setOrgInfoDownloadResponseVoList(orgInfoDownloadResponseVoList);
        template.setOrgDeliveryInfoDownloadResponseVoList(orgDeliveryInfoDownloadResponseVoList);
        template.setOrgInvoiceInfoDownloadResponseVoList(orgInvoiceInfoDownloadResponseVoList);
        template.setOrgPostInfoDownloadResponseVoList(orgPostInfoDownloadResponseVoList);
        template.setFileName("组织信息");
        excelUtils.downloadExcelOrgInfo(response, template);
    }


    @RequestMapping("/downloadOrgInfoForUpdate")
    public void downloadOrgInfoForUpdate(@RequestBody GetOrgTreeRequest request, HttpServletResponse response) {
        //组织信息
        List<OrgInfoExcelColumnVO> orgInfoExcelColumnVOList = new ArrayList<>();
        //联系人信息
        List<OrgContactExcelColumnVO> orgContactExcelColumnVOList = new ArrayList<>();
        //发票信息
        List<OrgInvoiceInfoExcelColumnVO> orgInvoiceInfoExcelColumnVOList = new ArrayList<>();
        //配送地址
        List<OrgDeliveryInfoExcelColumnVO> orgDeliveryInfoExcelColumnVOList = new ArrayList<>();
        //组织设置
        List<OrgConfigExcelColumnVO> orgConfigExcelColumnVOList = new ArrayList<>();
        //支付设置
        List<PayTypeConfigExcelColumnVO> payTypeConfigExcelColumnVOList = new ArrayList<>();


        List<String> stringList = organizationInfoService.listAllDepartmentByOrgId(request);
        for (String oid : stringList) {
            //查询组织信息
            MbOrgInfo orgInfo = organizationInfoService.findByOrgId(oid);
            if (orgInfo.getId() < 0) {
                continue;
            }

            OrgInfoExcelColumnVO orgInfoExcelColumnVO = new OrgInfoExcelColumnVO();
            orgInfoExcelColumnVO.setIsDelete("否");
            orgInfoExcelColumnVO.setOrgId(orgInfo.getOrgId());
            orgInfoExcelColumnVO.setType(Objects.equals(OrgTypeEnum.C.getCode(), orgInfo.getOrgType()) ? OrgTypeEnum.C.getDesc() : OrgTypeEnum.D.getDesc());
            orgInfoExcelColumnVO.setParentBusinessCode(orgInfo.getParentBusinessCode());
            orgInfoExcelColumnVO.setIsActive(Objects.equals("T", orgInfo.getValid()) ? "是" : "否");
            orgInfoExcelColumnVO.setName(orgInfo.getName());
            orgInfoExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());

            OrgContactExcelColumnVO orgContactExcelColumnVO = new OrgContactExcelColumnVO();
            orgContactExcelColumnVO.setContactName(orgInfo.getContactName());
            orgContactExcelColumnVO.setContactEmail(orgInfo.getContactEmail());
            orgContactExcelColumnVO.setContactCountryCode(orgInfo.getContactAreaCode());
            orgContactExcelColumnVO.setContactPhone(orgInfo.getContactPhone());
            orgContactExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());

            Example example = new Example(MbOrgCostDefaultDepartment.class);
            example.createCriteria().andEqualTo("orgId", oid).andEqualTo("isDelete", false);
            List<MbOrgCostDefaultDepartment> mbOrgCostDefaultDepartments =
                    mbOrgCostDefaultDepartmentMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(mbOrgCostDefaultDepartments)) {
                MbOrgCostDefaultDepartment defaultDepartment = mbOrgCostDefaultDepartments.get(0);
                List<CostCenter> costCenterList = new ArrayList<>();
                List<MbOrgCostInfo> mbOrgCostInfos = orgCostInfoMapper.selectByOrgId(request.getOrgId());
                for (MbOrgCostInfo mbOrgCostInfo : mbOrgCostInfos) {
                    CostCenter transfer = transfer(mbOrgCostInfo);
                    if (Objects.nonNull(defaultDepartment)
                            && defaultDepartment.getCostInfoId().compareTo(mbOrgCostInfo.getId()) == 0) {
                        transfer.setIsDefault(Boolean.TRUE);
                    } else {
                        transfer.setIsDefault(Boolean.FALSE);
                    }
                    costCenterList.add(transfer);
                }

                orgInfoExcelColumnVO.setCostCenterInfo( costCenterList.stream()
                        .map(orgCost -> orgCost.getCostCenterName()+"/"+orgCost.getCostCenterCode())
                        .collect(Collectors.joining(";")));
                orgInfoExcelColumnVO.setCostCenterInfoDefault(costCenterList.stream()
                        .filter(orgCost -> orgCost.getIsDefault())
                        .map(orgCost -> orgCost.getCostCenterName()+"/"+orgCost.getCostCenterCode())
                        .collect(Collectors.joining(";")));
            }


            orgInfoExcelColumnVOList.add(orgInfoExcelColumnVO);
            if(StringUtils.isNotBlank(orgContactExcelColumnVO.getContactName())){
                orgContactExcelColumnVOList.add(orgContactExcelColumnVO);
            }

            //查询发票信息
            List<MbCommonInvoiceInfo> mbCommonInvoiceInfos = commonInvoiceInfoService.listByOrgIdReal(oid);
            mbCommonInvoiceInfos.stream().forEach(item -> {
                OrgInvoiceInfoExcelColumnVO orgInvoiceInfoExcelColumnVO = new OrgInvoiceInfoExcelColumnVO();
                orgInvoiceInfoExcelColumnVO.setAccountBank(item.getAccountBank());
                orgInvoiceInfoExcelColumnVO.setAccountCardNo(item.getAccountCardNo());
                orgInvoiceInfoExcelColumnVO.setTaxId(item.getTaxId());
                orgInvoiceInfoExcelColumnVO.setInvoiceTitle(item.getInvoiceTitle());
                orgInvoiceInfoExcelColumnVO.setCorporationPhone(item.getCorporationPhone());
                orgInvoiceInfoExcelColumnVO.setCorporationAddress(item.getCorporationAddress());
                orgInvoiceInfoExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());
                orgInvoiceInfoExcelColumnVOList.add(orgInvoiceInfoExcelColumnVO);
            });

            //查询配送地址
            List<MbExpressAddress> mbExpressAddresses = expressAddressService.listByOrgId(oid);
            if (OrgTypeEnum.D.getCode().equals(orgInfo.getOrgType()) && CollectionUtils.isEmpty(mbExpressAddresses)) {
                MbOrgInfo corpOrgInfo = iOrganizationInfoService.findRecentCompanyIdByOrgId(oid);
                mbExpressAddresses = expressAddressService.listByOrgId(corpOrgInfo.getOrgId());
            }
            mbExpressAddresses.stream().forEach(item -> {
                OrgDeliveryInfoExcelColumnVO orgDeliveryInfoExcelColumnVO = new OrgDeliveryInfoExcelColumnVO();
                if(item.getProvince()!=null){
                    orgDeliveryInfoExcelColumnVO.setProvinceName(item.getProvinceName());
                }
                if(item.getCity()!=null){
                    orgDeliveryInfoExcelColumnVO.setCityName(item.getCityName());
                }
                if(item.getDistrict()!=null){
                    orgDeliveryInfoExcelColumnVO.setDistrictName(item.getDistrictName());
                }



                orgDeliveryInfoExcelColumnVO.setAddress(item.getAddress());
                orgDeliveryInfoExcelColumnVO.setRecipientName(item.getRecipientName());
                orgDeliveryInfoExcelColumnVO.setRecipientCountryCode(item.getCountryCode());
                orgDeliveryInfoExcelColumnVO.setRecipientPhone(item.getRecipientPhone());
                orgDeliveryInfoExcelColumnVO.setIsDefault(CommonEnum.Y.getCode().equals(item.getIsDefault()) ? CommonEnum.Y.getDesc() : CommonEnum.N.getDesc());
                orgDeliveryInfoExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());
                orgDeliveryInfoExcelColumnVOList.add(orgDeliveryInfoExcelColumnVO);
            });

            //查询组织配置信息
            GetOrgConfigRequest getOrgConfigRequest = new GetOrgConfigRequest();
            getOrgConfigRequest.setOrgId(oid);
            GetOrgConfigResponse orgConfig = orgConfigService.getOrgConfig(getOrgConfigRequest);
            if(orgConfig != null){
                OrgConfigExcelColumnVO orgConfigExcelColumnVO = new OrgConfigExcelColumnVO();
                orgConfigExcelColumnVO.setCostCenterIsNeed( Optional.ofNullable(orgConfig.getOrgConfigInfo()).map(OrgConfigInfoVo::getCostCenterIsRequired).orElse("否") .equals("T")? "是" : "否");
                orgConfigExcelColumnVO.setProjectIsNeed(Optional.ofNullable(orgConfig.getOrgConfigInfo()).map(OrgConfigInfoVo::getProjectIsRequired).orElse("否") .equals("T")? "是" : "否");
                orgConfigExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());
                orgConfigExcelColumnVOList.add(orgConfigExcelColumnVO);
            }

            //查询支付配置信息
            List<MbOrgPayType> mbOrgPayTypeList = orgPayTypeService.findByOrdId(oid);

            Map<String, String> resMap = new HashMap<>();
            for (int i = 0; i < mbOrgPayTypeList.size(); i++) {

                MbOrgPayType item = mbOrgPayTypeList.get(i);
                if(item.getCorpPayType().equals(CorpPayTypeEnum.PUB.toString())){
                    String mapValue = resMap.get(item.getSite());
                    if(mapValue!= null){
                        mapValue = mapValue + "，" +  PayTypeEnum.getNameByType(item.getPaytype());
                    }else {
                        mapValue = PayTypeEnum.getNameByType(item.getPaytype());
                    }
                    resMap.put(item.getSite(),mapValue);
                }
            }
            if(CollectionUtils.isNotEmpty(resMap)){
                PayTypeConfigExcelColumnVO payTypeConfigExcelColumnVO = new PayTypeConfigExcelColumnVO();
                payTypeConfigExcelColumnVO.setBusinessCode(orgInfo.getBusinessCode());
                payTypeConfigExcelColumnVO.setCar(resMap.get(SiteEnum.CAR.getCode()));
                payTypeConfigExcelColumnVO.setFlight(resMap.get(SiteEnum.FLIGHT.getCode()));
                payTypeConfigExcelColumnVO.setFlightintl(resMap.get(SiteEnum.FLIGHTINTL.getCode()));
                payTypeConfigExcelColumnVO.setHotel(resMap.get(SiteEnum.HOTEL.getCode()));
                payTypeConfigExcelColumnVO.setHotelintl(resMap.get(SiteEnum.HOTELINTL.getCode()));
                payTypeConfigExcelColumnVO.setTrain(resMap.get(SiteEnum.TRAIN.getCode()));
                payTypeConfigExcelColumnVOList.add(payTypeConfigExcelColumnVO);
            }

        }

        OrgInfoDownloadTemplate template = new OrgInfoDownloadTemplate();
        template.setOrgInfoExcelColumnVOList(orgInfoExcelColumnVOList);
        template.setOrgContactExcelColumnVOList(orgContactExcelColumnVOList);
        template.setOrgInvoiceInfoExcelColumnVOList(orgInvoiceInfoExcelColumnVOList);
        template.setOrgDeliveryInfoExcelColumnVOList(orgDeliveryInfoExcelColumnVOList);
        template.setOrgConfigExcelColumnVOList(orgConfigExcelColumnVOList);
        template.setPayTypeConfigExcelColumnVOList(payTypeConfigExcelColumnVOList);
        template.setFileName("组织信息");
        excelUtils.downloadExcelOrgInfoWithLock(response, template);
    }

    /**
     * 获取上级第一个为公司的组织（包含当前组织）
     */
    public MbOrgInfo getCompanyInfo(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return null;
        }
        List<MbOrgInfo> infoList = mbOrgInfoMapper.listByOrgIds(Collections.singletonList(orgId));
        if (CollectionUtils.isNotEmpty(infoList)) {
            MbOrgInfo mbOrgInfo = infoList.get(0);
            if (OrganizationConst.COMPANY.equals(mbOrgInfo.getOrgType()) || StringUtils.isBlank(mbOrgInfo.getParentId())) {
                return mbOrgInfo;
            } else {
                return getCompanyInfo(mbOrgInfo.getParentId());
            }
        }
        return null;
    }

    /**
     * 实体转换
     *
     * @param model
     * @return
     */
    private CostCenter transfer(MbOrgCostInfo model) {
        CostCenter costInfo = new CostCenter();
        if (model.getId() != null && model.getId() > 0) {
            costInfo.setId(model.getId());
        }
        costInfo.setCompany(model.getCompany());
        costInfo.setCompanyId(model.getCompanyId());
        costInfo.setCostCenterCode(model.getCostCenterCode());
        costInfo.setCostCenterName(model.getCostCenterName());
        costInfo.setCostCenterNameAndCode(model.getCostCenterName()+"/"+model.getCostCenterCode());
        costInfo.setValid(model.getValid());
        if (model.getCreateDate() != null) {
            costInfo.setCreateDate(new SimpleDateFormat(DateUtil.DF_YMD).format(model.getCreateDate()));
        }
        costInfo.setValidStartDate(model.getValidStartDate());
        costInfo.setValidEndDate(model.getValidEndDate());
        costInfo.setUid(model.getOperatorUid());
        costInfo.setUserName(model.getOperatorName());
        costInfo.setLastUpdateTime(model.getUpdateTime());
        costInfo.setCostCenterId(Optional.ofNullable(model.getId()).map(String::valueOf).orElse(""));
        return costInfo;
    }


    @PostMapping("/downloadOrgsEmployeeInfo")
    public void downloadOrgsEmployeeInfo(@RequestBody GetOrgTreeRequest request, HttpServletResponse response) {
        List<EmployeeDownloadResponseVo> employeeDownloadResponseVoList = new ArrayList<>();
        List<EmployeeDownloadUserIdCardResponseVo> cardResponseVos = new ArrayList<>();
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = syncEmployeeNewService.findDownloadOrgsEmployeeInfo(request.getOrgIds());
        log.info("导出人员数据:{}",JsonUtils.toJsonString(orgEmployeeInfoList));
        for (MbOrgEmployeeInfo mbOrgEmployeeInfo : orgEmployeeInfoList) {
            EmployeeDownloadResponseVo employeeDownloadResponseVo = new EmployeeDownloadResponseVo();
            employeeDownloadResponseVo.setBirthday(DateUtil.dateToYMD(mbOrgEmployeeInfo.getBirthday()));
            employeeDownloadResponseVo.setCompanyName(EncryptUtils.sm4Decrypt(mbOrgEmployeeInfo.getCompanyName()));
            employeeDownloadResponseVo.setEmail(mbOrgEmployeeInfo.getEmail());
            employeeDownloadResponseVo.setFirstEnName(mbOrgEmployeeInfo.getFirstEnName());
            employeeDownloadResponseVo.setLastEnName(mbOrgEmployeeInfo.getLastEnName());
            employeeDownloadResponseVo.setGender(Null.or(mbOrgEmployeeInfo.getGender(), gender -> Null.or(GenderEnum.getByCode(gender), t->t.getDesc()), null));
            employeeDownloadResponseVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
            employeeDownloadResponseVo.setOrgName(EncryptUtils.sm4Decrypt(mbOrgEmployeeInfo.getOrgName()));
            employeeDownloadResponseVo.setPostName(mbOrgEmployeeInfo.getPostName());
            employeeDownloadResponseVo.setUid(mbOrgEmployeeInfo.getUid());
            employeeDownloadResponseVo.setName(mbOrgEmployeeInfo.getName());
            employeeDownloadResponseVo.setCountryCode(mbOrgEmployeeInfo.getAreaCode());
            employeeDownloadResponseVo.setNationality(replaceNationality(mbOrgEmployeeInfo.getNationality()));
            employeeDownloadResponseVoList.add(employeeDownloadResponseVo);
        }
        List<String> uidList = orgEmployeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        List<MbOrgUserIdcard> userIdCards = syncEmployeeNewService.findOrgUserIdCard(uidList);
        for (MbOrgUserIdcard userIdCard : userIdCards) {
            EmployeeDownloadUserIdCardResponseVo vo = buildUserIdCard(userIdCard);
            cardResponseVos.add(vo);
        }
        EmployeeDownloadTemplate template = new EmployeeDownloadTemplate();
        template.setEmployeeDownloadResponseVoList(employeeDownloadResponseVoList);
        template.setEmployeeDownloadUserIdCardResponseVoList(cardResponseVos);
        template.setFileName("人员信息");
        excelUtils.downloadExcelEmployee(response, template);
    }

    private void confirmGenderAndBirthDay(Map<String, List<EmployeeCardTypeInfoColumnVO>> empCardMap, List<EmployeeInfoExcelColumnVO> employeeInfo) {
        employeeInfo.forEach(e ->{
            if (empCardMap.containsKey(e.getUid()) && CollectionUtils.isNotEmpty(empCardMap.get(e.getUid()))) {
                // 特定类型的证件号码转大写
                empCardMap.get(e.getUid()).forEach(k ->{
                    if (CardEnum.needUpperCaseCard(k.getCardType())){
                        k.setCardNo(k.getCardNo().toUpperCase());
                    }
                });
                //根据身份证号码确定性别生日信息
                List<EmployeeCardTypeInfoColumnVO> idCards = empCardMap.get(e.getUid()).stream().filter(k -> CardEnum.ID_CARD.getName().equals(k.getCardType())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(idCards)) {
                    String cardNo = idCards.get(0).getCardNo();
                    e.setBirthday(IdCardUtil.getBirth(cardNo));
                    e.setGender(IdCardUtil.getGender(cardNo));
                }
            }
        });
    }
}
